aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManu Abraham <abraham.manu@gmail.com>2011-11-24 09:59:53 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-12-30 12:50:29 -0500
commit14c038627e275f7ccec4761350783340a7c1ae2b (patch)
tree32446599e6c9d68b5004d3d2a55f5906c9c3ce74
parent1ca8dde859844c50e043182060acf14be5288463 (diff)
[media] CXD2820r: Query DVB frontend delivery capabilities
Override default delivery system information provided by FE_GET_INFO, so that applications can enumerate delivery systems provided by the frontend. Signed-off-by: Manu Abraham <abraham.manu@gmail.com> Acked-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_c.c2
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_core.c651
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_priv.h5
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t.c2
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t2.c2
5 files changed, 221 insertions, 441 deletions
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
index c4128773f2ee..9847d3511017 100644
--- a/drivers/media/dvb/frontends/cxd2820r_c.c
+++ b/drivers/media/dvb/frontends/cxd2820r_c.c
@@ -22,7 +22,7 @@
22#include "cxd2820r_priv.h" 22#include "cxd2820r_priv.h"
23 23
24int cxd2820r_set_frontend_c(struct dvb_frontend *fe, 24int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params) 25 struct dvb_frontend_parameters *params)
26{ 26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv; 27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
index 036480f967b7..5b0120a75d61 100644
--- a/drivers/media/dvb/frontends/cxd2820r_core.c
+++ b/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -240,43 +240,6 @@ error:
240 return ret; 240 return ret;
241} 241}
242 242
243/* lock FE */
244static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
245{
246 int ret = 0;
247 dbg("%s: active_fe=%d", __func__, active_fe);
248
249 mutex_lock(&priv->fe_lock);
250
251 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
252 if (priv->active_fe == active_fe)
253 ;
254 else if (priv->active_fe == -1)
255 priv->active_fe = active_fe;
256 else
257 ret = -EBUSY;
258
259 mutex_unlock(&priv->fe_lock);
260
261 return ret;
262}
263
264/* unlock FE */
265static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
266{
267 dbg("%s: active_fe=%d", __func__, active_fe);
268
269 mutex_lock(&priv->fe_lock);
270
271 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
272 if (priv->active_fe == active_fe)
273 priv->active_fe = -1;
274
275 mutex_unlock(&priv->fe_lock);
276
277 return;
278}
279
280/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */ 243/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
281u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor) 244u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
282{ 245{
@@ -284,378 +247,230 @@ u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
284} 247}
285 248
286static int cxd2820r_set_frontend(struct dvb_frontend *fe, 249static int cxd2820r_set_frontend(struct dvb_frontend *fe,
287 struct dvb_frontend_parameters *p) 250 struct dvb_frontend_parameters *p)
288{ 251{
289 struct cxd2820r_priv *priv = fe->demodulator_priv;
290 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 252 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
291 int ret; 253 int ret;
292 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
293
294 if (fe->ops.info.type == FE_OFDM) {
295 /* DVB-T/T2 */
296 ret = cxd2820r_lock(priv, 0);
297 if (ret)
298 return ret;
299
300 switch (priv->delivery_system) {
301 case SYS_UNDEFINED:
302 if (c->delivery_system == SYS_DVBT) {
303 /* SLEEP => DVB-T */
304 ret = cxd2820r_set_frontend_t(fe, p);
305 } else {
306 /* SLEEP => DVB-T2 */
307 ret = cxd2820r_set_frontend_t2(fe, p);
308 }
309 break;
310 case SYS_DVBT:
311 if (c->delivery_system == SYS_DVBT) {
312 /* DVB-T => DVB-T */
313 ret = cxd2820r_set_frontend_t(fe, p);
314 } else if (c->delivery_system == SYS_DVBT2) {
315 /* DVB-T => DVB-T2 */
316 ret = cxd2820r_sleep_t(fe);
317 if (ret)
318 break;
319 ret = cxd2820r_set_frontend_t2(fe, p);
320 }
321 break;
322 case SYS_DVBT2:
323 if (c->delivery_system == SYS_DVBT2) {
324 /* DVB-T2 => DVB-T2 */
325 ret = cxd2820r_set_frontend_t2(fe, p);
326 } else if (c->delivery_system == SYS_DVBT) {
327 /* DVB-T2 => DVB-T */
328 ret = cxd2820r_sleep_t2(fe);
329 if (ret)
330 break;
331 ret = cxd2820r_set_frontend_t(fe, p);
332 }
333 break;
334 default:
335 dbg("%s: error state=%d", __func__,
336 priv->delivery_system);
337 ret = -EINVAL;
338 }
339 } else {
340 /* DVB-C */
341 ret = cxd2820r_lock(priv, 1);
342 if (ret)
343 return ret;
344 254
255 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
256 switch (c->delivery_system) {
257 case SYS_DVBT:
258 ret = cxd2820r_init_t(fe);
259 if (ret < 0)
260 goto err;
261 ret = cxd2820r_set_frontend_t(fe, p);
262 if (ret < 0)
263 goto err;
264 break;
265 case SYS_DVBT2:
266 ret = cxd2820r_init_t(fe);
267 if (ret < 0)
268 goto err;
269 ret = cxd2820r_set_frontend_t2(fe, p);
270 if (ret < 0)
271 goto err;
272 break;
273 case SYS_DVBC_ANNEX_AC:
274 ret = cxd2820r_init_c(fe);
275 if (ret < 0)
276 goto err;
345 ret = cxd2820r_set_frontend_c(fe, p); 277 ret = cxd2820r_set_frontend_c(fe, p);
278 if (ret < 0)
279 goto err;
280 break;
281 default:
282 dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system);
283 ret = -EINVAL;
284 break;
346 } 285 }
347 286err:
348 return ret; 287 return ret;
349} 288}
350
351static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status) 289static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
352{ 290{
353 struct cxd2820r_priv *priv = fe->demodulator_priv;
354 int ret; 291 int ret;
355 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
356
357 if (fe->ops.info.type == FE_OFDM) {
358 /* DVB-T/T2 */
359 ret = cxd2820r_lock(priv, 0);
360 if (ret)
361 return ret;
362
363 switch (fe->dtv_property_cache.delivery_system) {
364 case SYS_DVBT:
365 ret = cxd2820r_read_status_t(fe, status);
366 break;
367 case SYS_DVBT2:
368 ret = cxd2820r_read_status_t2(fe, status);
369 break;
370 default:
371 ret = -EINVAL;
372 }
373 } else {
374 /* DVB-C */
375 ret = cxd2820r_lock(priv, 1);
376 if (ret)
377 return ret;
378 292
293 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
294 switch (fe->dtv_property_cache.delivery_system) {
295 case SYS_DVBT:
296 ret = cxd2820r_read_status_t(fe, status);
297 break;
298 case SYS_DVBT2:
299 ret = cxd2820r_read_status_t2(fe, status);
300 break;
301 case SYS_DVBC_ANNEX_AC:
379 ret = cxd2820r_read_status_c(fe, status); 302 ret = cxd2820r_read_status_c(fe, status);
303 break;
304 default:
305 ret = -EINVAL;
306 break;
380 } 307 }
381
382 return ret; 308 return ret;
383} 309}
384 310
385static int cxd2820r_get_frontend(struct dvb_frontend *fe, 311static int cxd2820r_get_frontend(struct dvb_frontend *fe,
386 struct dvb_frontend_parameters *p) 312 struct dvb_frontend_parameters *p)
387{ 313{
388 struct cxd2820r_priv *priv = fe->demodulator_priv;
389 int ret; 314 int ret;
390 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
391
392 if (fe->ops.info.type == FE_OFDM) {
393 /* DVB-T/T2 */
394 ret = cxd2820r_lock(priv, 0);
395 if (ret)
396 return ret;
397
398 switch (fe->dtv_property_cache.delivery_system) {
399 case SYS_DVBT:
400 ret = cxd2820r_get_frontend_t(fe, p);
401 break;
402 case SYS_DVBT2:
403 ret = cxd2820r_get_frontend_t2(fe, p);
404 break;
405 default:
406 ret = -EINVAL;
407 }
408 } else {
409 /* DVB-C */
410 ret = cxd2820r_lock(priv, 1);
411 if (ret)
412 return ret;
413 315
316 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
317 switch (fe->dtv_property_cache.delivery_system) {
318 case SYS_DVBT:
319 ret = cxd2820r_get_frontend_t(fe, p);
320 break;
321 case SYS_DVBT2:
322 ret = cxd2820r_get_frontend_t2(fe, p);
323 break;
324 case SYS_DVBC_ANNEX_AC:
414 ret = cxd2820r_get_frontend_c(fe, p); 325 ret = cxd2820r_get_frontend_c(fe, p);
326 break;
327 default:
328 ret = -EINVAL;
329 break;
415 } 330 }
416
417 return ret; 331 return ret;
418} 332}
419 333
420static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) 334static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
421{ 335{
422 struct cxd2820r_priv *priv = fe->demodulator_priv;
423 int ret; 336 int ret;
424 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
425
426 if (fe->ops.info.type == FE_OFDM) {
427 /* DVB-T/T2 */
428 ret = cxd2820r_lock(priv, 0);
429 if (ret)
430 return ret;
431
432 switch (fe->dtv_property_cache.delivery_system) {
433 case SYS_DVBT:
434 ret = cxd2820r_read_ber_t(fe, ber);
435 break;
436 case SYS_DVBT2:
437 ret = cxd2820r_read_ber_t2(fe, ber);
438 break;
439 default:
440 ret = -EINVAL;
441 }
442 } else {
443 /* DVB-C */
444 ret = cxd2820r_lock(priv, 1);
445 if (ret)
446 return ret;
447 337
338 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
339 switch (fe->dtv_property_cache.delivery_system) {
340 case SYS_DVBT:
341 ret = cxd2820r_read_ber_t(fe, ber);
342 break;
343 case SYS_DVBT2:
344 ret = cxd2820r_read_ber_t2(fe, ber);
345 break;
346 case SYS_DVBC_ANNEX_AC:
448 ret = cxd2820r_read_ber_c(fe, ber); 347 ret = cxd2820r_read_ber_c(fe, ber);
348 break;
349 default:
350 ret = -EINVAL;
351 break;
449 } 352 }
450
451 return ret; 353 return ret;
452} 354}
453 355
454static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 356static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
455{ 357{
456 struct cxd2820r_priv *priv = fe->demodulator_priv;
457 int ret; 358 int ret;
458 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
459
460 if (fe->ops.info.type == FE_OFDM) {
461 /* DVB-T/T2 */
462 ret = cxd2820r_lock(priv, 0);
463 if (ret)
464 return ret;
465
466 switch (fe->dtv_property_cache.delivery_system) {
467 case SYS_DVBT:
468 ret = cxd2820r_read_signal_strength_t(fe, strength);
469 break;
470 case SYS_DVBT2:
471 ret = cxd2820r_read_signal_strength_t2(fe, strength);
472 break;
473 default:
474 ret = -EINVAL;
475 }
476 } else {
477 /* DVB-C */
478 ret = cxd2820r_lock(priv, 1);
479 if (ret)
480 return ret;
481 359
360 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
361 switch (fe->dtv_property_cache.delivery_system) {
362 case SYS_DVBT:
363 ret = cxd2820r_read_signal_strength_t(fe, strength);
364 break;
365 case SYS_DVBT2:
366 ret = cxd2820r_read_signal_strength_t2(fe, strength);
367 break;
368 case SYS_DVBC_ANNEX_AC:
482 ret = cxd2820r_read_signal_strength_c(fe, strength); 369 ret = cxd2820r_read_signal_strength_c(fe, strength);
370 break;
371 default:
372 ret = -EINVAL;
373 break;
483 } 374 }
484
485 return ret; 375 return ret;
486} 376}
487 377
488static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) 378static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
489{ 379{
490 struct cxd2820r_priv *priv = fe->demodulator_priv;
491 int ret; 380 int ret;
492 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
493
494 if (fe->ops.info.type == FE_OFDM) {
495 /* DVB-T/T2 */
496 ret = cxd2820r_lock(priv, 0);
497 if (ret)
498 return ret;
499
500 switch (fe->dtv_property_cache.delivery_system) {
501 case SYS_DVBT:
502 ret = cxd2820r_read_snr_t(fe, snr);
503 break;
504 case SYS_DVBT2:
505 ret = cxd2820r_read_snr_t2(fe, snr);
506 break;
507 default:
508 ret = -EINVAL;
509 }
510 } else {
511 /* DVB-C */
512 ret = cxd2820r_lock(priv, 1);
513 if (ret)
514 return ret;
515 381
382 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
383 switch (fe->dtv_property_cache.delivery_system) {
384 case SYS_DVBT:
385 ret = cxd2820r_read_snr_t(fe, snr);
386 break;
387 case SYS_DVBT2:
388 ret = cxd2820r_read_snr_t2(fe, snr);
389 break;
390 case SYS_DVBC_ANNEX_AC:
516 ret = cxd2820r_read_snr_c(fe, snr); 391 ret = cxd2820r_read_snr_c(fe, snr);
392 break;
393 default:
394 ret = -EINVAL;
395 break;
517 } 396 }
518
519 return ret; 397 return ret;
520} 398}
521 399
522static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 400static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
523{ 401{
524 struct cxd2820r_priv *priv = fe->demodulator_priv;
525 int ret; 402 int ret;
526 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
527
528 if (fe->ops.info.type == FE_OFDM) {
529 /* DVB-T/T2 */
530 ret = cxd2820r_lock(priv, 0);
531 if (ret)
532 return ret;
533
534 switch (fe->dtv_property_cache.delivery_system) {
535 case SYS_DVBT:
536 ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
537 break;
538 case SYS_DVBT2:
539 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
540 break;
541 default:
542 ret = -EINVAL;
543 }
544 } else {
545 /* DVB-C */
546 ret = cxd2820r_lock(priv, 1);
547 if (ret)
548 return ret;
549 403
404 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
405 switch (fe->dtv_property_cache.delivery_system) {
406 case SYS_DVBT:
407 ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
408 break;
409 case SYS_DVBT2:
410 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
411 break;
412 case SYS_DVBC_ANNEX_AC:
550 ret = cxd2820r_read_ucblocks_c(fe, ucblocks); 413 ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
414 break;
415 default:
416 ret = -EINVAL;
417 break;
551 } 418 }
552
553 return ret; 419 return ret;
554} 420}
555 421
556static int cxd2820r_init(struct dvb_frontend *fe) 422static int cxd2820r_init(struct dvb_frontend *fe)
557{ 423{
558 struct cxd2820r_priv *priv = fe->demodulator_priv; 424 return 0;
559 int ret;
560 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
561
562 priv->delivery_system = SYS_UNDEFINED;
563 /* delivery system is unknown at that (init) phase */
564
565 if (fe->ops.info.type == FE_OFDM) {
566 /* DVB-T/T2 */
567 ret = cxd2820r_lock(priv, 0);
568 if (ret)
569 return ret;
570
571 ret = cxd2820r_init_t(fe);
572 } else {
573 /* DVB-C */
574 ret = cxd2820r_lock(priv, 1);
575 if (ret)
576 return ret;
577
578 ret = cxd2820r_init_c(fe);
579 }
580
581 return ret;
582} 425}
583 426
584static int cxd2820r_sleep(struct dvb_frontend *fe) 427static int cxd2820r_sleep(struct dvb_frontend *fe)
585{ 428{
586 struct cxd2820r_priv *priv = fe->demodulator_priv;
587 int ret; 429 int ret;
588 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
589
590 if (fe->ops.info.type == FE_OFDM) {
591 /* DVB-T/T2 */
592 ret = cxd2820r_lock(priv, 0);
593 if (ret)
594 return ret;
595
596 switch (fe->dtv_property_cache.delivery_system) {
597 case SYS_DVBT:
598 ret = cxd2820r_sleep_t(fe);
599 break;
600 case SYS_DVBT2:
601 ret = cxd2820r_sleep_t2(fe);
602 break;
603 default:
604 ret = -EINVAL;
605 }
606
607 cxd2820r_unlock(priv, 0);
608 } else {
609 /* DVB-C */
610 ret = cxd2820r_lock(priv, 1);
611 if (ret)
612 return ret;
613 430
431 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
432 switch (fe->dtv_property_cache.delivery_system) {
433 case SYS_DVBT:
434 ret = cxd2820r_sleep_t(fe);
435 break;
436 case SYS_DVBT2:
437 ret = cxd2820r_sleep_t2(fe);
438 break;
439 case SYS_DVBC_ANNEX_AC:
614 ret = cxd2820r_sleep_c(fe); 440 ret = cxd2820r_sleep_c(fe);
615 441 break;
616 cxd2820r_unlock(priv, 1); 442 default:
443 ret = -EINVAL;
444 break;
617 } 445 }
618
619 return ret; 446 return ret;
620} 447}
621 448
622static int cxd2820r_get_tune_settings(struct dvb_frontend *fe, 449static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
623 struct dvb_frontend_tune_settings *s) 450 struct dvb_frontend_tune_settings *s)
624{ 451{
625 struct cxd2820r_priv *priv = fe->demodulator_priv;
626 int ret; 452 int ret;
627 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
628
629 if (fe->ops.info.type == FE_OFDM) {
630 /* DVB-T/T2 */
631 ret = cxd2820r_lock(priv, 0);
632 if (ret)
633 return ret;
634
635 switch (fe->dtv_property_cache.delivery_system) {
636 case SYS_DVBT:
637 ret = cxd2820r_get_tune_settings_t(fe, s);
638 break;
639 case SYS_DVBT2:
640 ret = cxd2820r_get_tune_settings_t2(fe, s);
641 break;
642 default:
643 ret = -EINVAL;
644 }
645 } else {
646 /* DVB-C */
647 ret = cxd2820r_lock(priv, 1);
648 if (ret)
649 return ret;
650 453
454 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
455 switch (fe->dtv_property_cache.delivery_system) {
456 case SYS_DVBT:
457 ret = cxd2820r_get_tune_settings_t(fe, s);
458 break;
459 case SYS_DVBT2:
460 ret = cxd2820r_get_tune_settings_t2(fe, s);
461 break;
462 case SYS_DVBC_ANNEX_AC:
651 ret = cxd2820r_get_tune_settings_c(fe, s); 463 ret = cxd2820r_get_tune_settings_c(fe, s);
464 break;
465 default:
466 ret = -EINVAL;
467 break;
652 } 468 }
653
654 return ret; 469 return ret;
655} 470}
656 471
657static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe, 472static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
658 struct dvb_frontend_parameters *p) 473 struct dvb_frontend_parameters *p)
659{ 474{
660 struct cxd2820r_priv *priv = fe->demodulator_priv; 475 struct cxd2820r_priv *priv = fe->demodulator_priv;
661 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 476 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -664,7 +479,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
664 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system); 479 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
665 480
666 /* switch between DVB-T and DVB-T2 when tune fails */ 481 /* switch between DVB-T and DVB-T2 when tune fails */
667 if (priv->last_tune_failed) { 482 if (priv->last_tune_failed && (priv->delivery_system != SYS_DVBC_ANNEX_AC)) {
668 if (priv->delivery_system == SYS_DVBT) 483 if (priv->delivery_system == SYS_DVBT)
669 c->delivery_system = SYS_DVBT2; 484 c->delivery_system = SYS_DVBT2;
670 else 485 else
@@ -727,9 +542,7 @@ static void cxd2820r_release(struct dvb_frontend *fe)
727 struct cxd2820r_priv *priv = fe->demodulator_priv; 542 struct cxd2820r_priv *priv = fe->demodulator_priv;
728 dbg("%s", __func__); 543 dbg("%s", __func__);
729 544
730 if (fe->ops.info.type == FE_OFDM) 545 kfree(priv);
731 kfree(priv);
732
733 return; 546 return;
734} 547}
735 548
@@ -742,128 +555,98 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
742 return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); 555 return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
743} 556}
744 557
745static const struct dvb_frontend_ops cxd2820r_ops[2]; 558static int cxd2820r_get_property(struct dvb_frontend *fe, struct dtv_property *p)
746
747struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
748 struct i2c_adapter *i2c, struct dvb_frontend *fe)
749{ 559{
750 int ret; 560 dbg("%s()\n", __func__);
751 struct cxd2820r_priv *priv = NULL; 561
752 u8 tmp; 562 switch (p->cmd) {
563 case DTV_ENUM_DELSYS:
564 p->u.buffer.data[0] = SYS_DVBT;
565 p->u.buffer.data[1] = SYS_DVBT2;
566 p->u.buffer.data[2] = SYS_DVBC_ANNEX_AC;
567 p->u.buffer.len = 3;
568 break;
569 default:
570 break;
571 }
572 return 0;
573}
753 574
754 if (fe == NULL) { 575static const struct dvb_frontend_ops cxd2820r_ops = {
755 /* FE0 */ 576 /* default: DVB-T/T2 */
756 /* allocate memory for the internal priv */ 577 .info = {
757 priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL); 578 .name = "Sony CXD2820R (DVB-T/T2)",
758 if (priv == NULL) 579 .type = FE_OFDM,
759 goto error; 580
581 .caps = FE_CAN_FEC_1_2 |
582 FE_CAN_FEC_2_3 |
583 FE_CAN_FEC_3_4 |
584 FE_CAN_FEC_5_6 |
585 FE_CAN_FEC_7_8 |
586 FE_CAN_FEC_AUTO |
587 FE_CAN_QPSK |
588 FE_CAN_QAM_16 |
589 FE_CAN_QAM_64 |
590 FE_CAN_QAM_256 |
591 FE_CAN_QAM_AUTO |
592 FE_CAN_TRANSMISSION_MODE_AUTO |
593 FE_CAN_GUARD_INTERVAL_AUTO |
594 FE_CAN_HIERARCHY_AUTO |
595 FE_CAN_MUTE_TS |
596 FE_CAN_2G_MODULATION
597 },
760 598
761 /* setup the priv */ 599 .release = cxd2820r_release,
762 priv->i2c = i2c; 600 .init = cxd2820r_init,
763 memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config)); 601 .sleep = cxd2820r_sleep,
764 mutex_init(&priv->fe_lock);
765 602
766 priv->active_fe = -1; /* NONE */ 603 .get_tune_settings = cxd2820r_get_tune_settings,
604 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,
767 605
768 /* check if the demod is there */ 606 .get_frontend = cxd2820r_get_frontend,
769 priv->bank[0] = priv->bank[1] = 0xff;
770 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
771 dbg("%s: chip id=%02x", __func__, tmp);
772 if (ret || tmp != 0xe1)
773 goto error;
774 607
775 /* create frontends */ 608 .get_frontend_algo = cxd2820r_get_frontend_algo,
776 memcpy(&priv->fe[0].ops, &cxd2820r_ops[0], 609 .search = cxd2820r_search,
777 sizeof(struct dvb_frontend_ops));
778 memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
779 sizeof(struct dvb_frontend_ops));
780 610
781 priv->fe[0].demodulator_priv = priv; 611 .read_status = cxd2820r_read_status,
782 priv->fe[1].demodulator_priv = priv; 612 .read_snr = cxd2820r_read_snr,
613 .read_ber = cxd2820r_read_ber,
614 .read_ucblocks = cxd2820r_read_ucblocks,
615 .read_signal_strength = cxd2820r_read_signal_strength,
783 616
784 return &priv->fe[0]; 617 .get_property = cxd2820r_get_property,
618};
785 619
786 } else { 620struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
787 /* FE1: FE0 given as pointer, just return FE1 we have 621 struct i2c_adapter *i2c,
788 * already created */ 622 struct dvb_frontend *fe)
789 priv = fe->demodulator_priv; 623{
790 return &priv->fe[1]; 624 struct cxd2820r_priv *priv = NULL;
791 } 625 int ret;
626 u8 tmp;
627
628 priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL);
629 if (!priv)
630 goto error;
792 631
632 priv->i2c = i2c;
633 memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config));
634
635 priv->bank[0] = priv->bank[1] = 0xff;
636 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
637 dbg("%s: chip id=%02x", __func__, tmp);
638 if (ret || tmp != 0xe1)
639 goto error;
640
641 memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops));
642 priv->fe.demodulator_priv = priv;
643 return &priv->fe;
793error: 644error:
794 kfree(priv); 645 kfree(priv);
795 return NULL; 646 return NULL;
796} 647}
797EXPORT_SYMBOL(cxd2820r_attach); 648EXPORT_SYMBOL(cxd2820r_attach);
798 649
799static const struct dvb_frontend_ops cxd2820r_ops[2] = {
800 {
801 /* DVB-T/T2 */
802 .info = {
803 .name = "Sony CXD2820R (DVB-T/T2)",
804 .type = FE_OFDM,
805 .caps =
806 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
807 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
808 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
809 FE_CAN_QPSK | FE_CAN_QAM_16 |
810 FE_CAN_QAM_64 | FE_CAN_QAM_256 |
811 FE_CAN_QAM_AUTO |
812 FE_CAN_TRANSMISSION_MODE_AUTO |
813 FE_CAN_GUARD_INTERVAL_AUTO |
814 FE_CAN_HIERARCHY_AUTO |
815 FE_CAN_MUTE_TS |
816 FE_CAN_2G_MODULATION
817 },
818
819 .release = cxd2820r_release,
820 .init = cxd2820r_init,
821 .sleep = cxd2820r_sleep,
822
823 .get_tune_settings = cxd2820r_get_tune_settings,
824 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,
825
826 .get_frontend = cxd2820r_get_frontend,
827
828 .get_frontend_algo = cxd2820r_get_frontend_algo,
829 .search = cxd2820r_search,
830
831 .read_status = cxd2820r_read_status,
832 .read_snr = cxd2820r_read_snr,
833 .read_ber = cxd2820r_read_ber,
834 .read_ucblocks = cxd2820r_read_ucblocks,
835 .read_signal_strength = cxd2820r_read_signal_strength,
836 },
837 {
838 /* DVB-C */
839 .info = {
840 .name = "Sony CXD2820R (DVB-C)",
841 .type = FE_QAM,
842 .caps =
843 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
844 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
845 FE_CAN_FEC_AUTO
846 },
847
848 .release = cxd2820r_release,
849 .init = cxd2820r_init,
850 .sleep = cxd2820r_sleep,
851
852 .get_tune_settings = cxd2820r_get_tune_settings,
853 .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,
854
855 .set_frontend = cxd2820r_set_frontend,
856 .get_frontend = cxd2820r_get_frontend,
857
858 .read_status = cxd2820r_read_status,
859 .read_snr = cxd2820r_read_snr,
860 .read_ber = cxd2820r_read_ber,
861 .read_ucblocks = cxd2820r_read_ucblocks,
862 .read_signal_strength = cxd2820r_read_signal_strength,
863 },
864};
865
866
867MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 650MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
868MODULE_DESCRIPTION("Sony CXD2820R demodulator driver"); 651MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
869MODULE_LICENSE("GPL"); 652MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
index 95539134efdb..94dcf7f0dbab 100644
--- a/drivers/media/dvb/frontends/cxd2820r_priv.h
+++ b/drivers/media/dvb/frontends/cxd2820r_priv.h
@@ -48,12 +48,9 @@ struct reg_val_mask {
48 48
49struct cxd2820r_priv { 49struct cxd2820r_priv {
50 struct i2c_adapter *i2c; 50 struct i2c_adapter *i2c;
51 struct dvb_frontend fe[2]; 51 struct dvb_frontend fe;
52 struct cxd2820r_config cfg; 52 struct cxd2820r_config cfg;
53 53
54 struct mutex fe_lock; /* FE lock */
55 int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
56
57 bool ber_running; 54 bool ber_running;
58 55
59 u8 bank[2]; 56 u8 bank[2];
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
index b1450ac4b683..4ce0576c87e4 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t.c
@@ -22,7 +22,7 @@
22#include "cxd2820r_priv.h" 22#include "cxd2820r_priv.h"
23 23
24int cxd2820r_set_frontend_t(struct dvb_frontend *fe, 24int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *p) 25 struct dvb_frontend_parameters *p)
26{ 26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv; 27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
index e21fc97291a8..76e3c83127e8 100644
--- a/drivers/media/dvb/frontends/cxd2820r_t2.c
+++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
@@ -22,7 +22,7 @@
22#include "cxd2820r_priv.h" 22#include "cxd2820r_priv.h"
23 23
24int cxd2820r_set_frontend_t2(struct dvb_frontend *fe, 24int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params) 25 struct dvb_frontend_parameters *params)
26{ 26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv; 27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;