aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-11-24 16:16:46 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:39 -0500
commit76efd62f1546c6fab2116d3ba832403387bd3d4a (patch)
tree2dacbc15f37de125aa573708f599913f5fe05e91
parent5d302f2e2c5fce46d88a9f6b3c1f74f9e9240e25 (diff)
V4L/DVB (9825): msp3400: convert to v4l2_subdev.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/msp3400-driver.c402
-rw-r--r--drivers/media/video/msp3400-driver.h7
-rw-r--r--drivers/media/video/msp3400-kthreads.c34
3 files changed, 247 insertions, 196 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 3da74dcee902..79ae7bd23528 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -51,14 +51,14 @@
51#include <linux/module.h> 51#include <linux/module.h>
52#include <linux/slab.h> 52#include <linux/slab.h>
53#include <linux/i2c.h> 53#include <linux/i2c.h>
54#include <linux/kthread.h>
55#include <linux/freezer.h>
54#include <linux/videodev2.h> 56#include <linux/videodev2.h>
55#include <media/v4l2-common.h> 57#include <media/v4l2-device.h>
56#include <media/v4l2-ioctl.h> 58#include <media/v4l2-ioctl.h>
57#include <media/v4l2-i2c-drv-legacy.h> 59#include <media/v4l2-i2c-drv-legacy.h>
58#include <media/tvaudio.h>
59#include <media/msp3400.h> 60#include <media/msp3400.h>
60#include <linux/kthread.h> 61#include <media/tvaudio.h>
61#include <linux/freezer.h>
62#include "msp3400-driver.h" 62#include "msp3400-driver.h"
63 63
64/* ---------------------------------------------------------------------- */ 64/* ---------------------------------------------------------------------- */
@@ -265,7 +265,7 @@ static char *scart_names[] = {
265 265
266void msp_set_scart(struct i2c_client *client, int in, int out) 266void msp_set_scart(struct i2c_client *client, int in, int out)
267{ 267{
268 struct msp_state *state = i2c_get_clientdata(client); 268 struct msp_state *state = to_state(i2c_get_clientdata(client));
269 269
270 state->in_scart = in; 270 state->in_scart = in;
271 271
@@ -289,7 +289,7 @@ void msp_set_scart(struct i2c_client *client, int in, int out)
289 289
290void msp_set_audio(struct i2c_client *client) 290void msp_set_audio(struct i2c_client *client)
291{ 291{
292 struct msp_state *state = i2c_get_clientdata(client); 292 struct msp_state *state = to_state(i2c_get_clientdata(client));
293 int bal = 0, bass, treble, loudness; 293 int bal = 0, bass, treble, loudness;
294 int val = 0; 294 int val = 0;
295 int reallymuted = state->muted | state->scan_in_progress; 295 int reallymuted = state->muted | state->scan_in_progress;
@@ -336,7 +336,7 @@ void msp_set_audio(struct i2c_client *client)
336 336
337static void msp_wake_thread(struct i2c_client *client) 337static void msp_wake_thread(struct i2c_client *client)
338{ 338{
339 struct msp_state *state = i2c_get_clientdata(client); 339 struct msp_state *state = to_state(i2c_get_clientdata(client));
340 340
341 if (NULL == state->kthread) 341 if (NULL == state->kthread)
342 return; 342 return;
@@ -390,9 +390,9 @@ static int msp_mode_v4l1_to_v4l2(int mode)
390} 390}
391#endif 391#endif
392 392
393static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 393static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
394{ 394{
395 struct msp_state *state = i2c_get_clientdata(client); 395 struct msp_state *state = to_state(sd);
396 396
397 switch (ctrl->id) { 397 switch (ctrl->id) {
398 case V4L2_CID_AUDIO_VOLUME: 398 case V4L2_CID_AUDIO_VOLUME:
@@ -433,9 +433,10 @@ static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
433 return 0; 433 return 0;
434} 434}
435 435
436static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) 436static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
437{ 437{
438 struct msp_state *state = i2c_get_clientdata(client); 438 struct msp_state *state = to_state(sd);
439 struct i2c_client *client = v4l2_get_subdevdata(sd);
439 440
440 switch (ctrl->id) { 441 switch (ctrl->id) {
441 case V4L2_CID_AUDIO_VOLUME: 442 case V4L2_CID_AUDIO_VOLUME:
@@ -481,40 +482,16 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
481 return 0; 482 return 0;
482} 483}
483 484
484static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 485#ifdef CONFIG_VIDEO_ALLOW_V4L1
486static int msp_ioctl(struct v4l2_subdev *sd, int cmd, void *arg)
485{ 487{
486 struct msp_state *state = i2c_get_clientdata(client); 488 struct msp_state *state = to_state(sd);
487 489 struct i2c_client *client = v4l2_get_subdevdata(sd);
488 if (msp_debug >= 2)
489 v4l_i2c_print_ioctl(client, cmd);
490 490
491 switch (cmd) { 491 switch (cmd) {
492 case AUDC_SET_RADIO:
493 if (state->radio)
494 return 0;
495 state->radio = 1;
496 v4l_dbg(1, msp_debug, client, "switching to radio mode\n");
497 state->watch_stereo = 0;
498 switch (state->opmode) {
499 case OPMODE_MANUAL:
500 /* set msp3400 to FM radio mode */
501 msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
502 msp3400c_set_carrier(client, MSP_CARRIER(10.7),
503 MSP_CARRIER(10.7));
504 msp_set_audio(client);
505 break;
506 case OPMODE_AUTODETECT:
507 case OPMODE_AUTOSELECT:
508 /* the thread will do for us */
509 msp_wake_thread(client);
510 break;
511 }
512 break;
513
514 /* --- v4l ioctls --- */ 492 /* --- v4l ioctls --- */
515 /* take care: bttv does userspace copying, we'll get a 493 /* take care: bttv does userspace copying, we'll get a
516 kernel pointer here... */ 494 kernel pointer here... */
517#ifdef CONFIG_VIDEO_ALLOW_V4L1
518 case VIDIOCGAUDIO: 495 case VIDIOCGAUDIO:
519 { 496 {
520 struct video_audio *va = arg; 497 struct video_audio *va = arg;
@@ -588,105 +565,137 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
588 msp_wake_thread(client); 565 msp_wake_thread(client);
589 break; 566 break;
590 } 567 }
591#endif 568 default:
592 case VIDIOC_S_FREQUENCY: 569 return -ENOIOCTLCMD;
593 {
594 /* new channel -- kick audio carrier scan */
595 msp_wake_thread(client);
596 break;
597 } 570 }
571 return 0;
572}
573#endif
598 574
599 /* --- v4l2 ioctls --- */ 575/* --- v4l2 ioctls --- */
600 case VIDIOC_S_STD: 576static int msp_s_radio(struct v4l2_subdev *sd)
601 { 577{
602 v4l2_std_id *id = arg; 578 struct msp_state *state = to_state(sd);
603 int update = state->radio || state->v4l2_std != *id; 579 struct i2c_client *client = v4l2_get_subdevdata(sd);
604 580
605 state->v4l2_std = *id; 581 if (state->radio)
606 state->radio = 0;
607 if (update)
608 msp_wake_thread(client);
609 return 0; 582 return 0;
583 state->radio = 1;
584 v4l_dbg(1, msp_debug, client, "switching to radio mode\n");
585 state->watch_stereo = 0;
586 switch (state->opmode) {
587 case OPMODE_MANUAL:
588 /* set msp3400 to FM radio mode */
589 msp3400c_set_mode(client, MSP_MODE_FM_RADIO);
590 msp3400c_set_carrier(client, MSP_CARRIER(10.7),
591 MSP_CARRIER(10.7));
592 msp_set_audio(client);
593 break;
594 case OPMODE_AUTODETECT:
595 case OPMODE_AUTOSELECT:
596 /* the thread will do for us */
597 msp_wake_thread(client);
598 break;
610 } 599 }
600 return 0;
601}
611 602
612 case VIDIOC_INT_G_AUDIO_ROUTING: 603static int msp_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
613 { 604{
614 struct v4l2_routing *rt = arg; 605 struct i2c_client *client = v4l2_get_subdevdata(sd);
615 606
616 *rt = state->routing; 607 /* new channel -- kick audio carrier scan */
617 break; 608 msp_wake_thread(client);
618 } 609 return 0;
610}
619 611
620 case VIDIOC_INT_S_AUDIO_ROUTING: 612static int msp_s_std(struct v4l2_subdev *sd, v4l2_std_id id)
621 { 613{
622 struct v4l2_routing *rt = arg; 614 struct msp_state *state = to_state(sd);
623 int tuner = (rt->input >> 3) & 1; 615 struct i2c_client *client = v4l2_get_subdevdata(sd);
624 int sc_in = rt->input & 0x7; 616 int update = state->radio || state->v4l2_std != id;
625 int sc1_out = rt->output & 0xf; 617
626 int sc2_out = (rt->output >> 4) & 0xf; 618 state->v4l2_std = id;
627 u16 val, reg; 619 state->radio = 0;
628 int i; 620 if (update)
629 int extern_input = 1;
630
631 if (state->routing.input == rt->input &&
632 state->routing.output == rt->output)
633 break;
634 state->routing = *rt;
635 /* check if the tuner input is used */
636 for (i = 0; i < 5; i++) {
637 if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
638 extern_input = 0;
639 }
640 state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
641 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
642 msp_set_scart(client, sc_in, 0);
643 msp_set_scart(client, sc1_out, 1);
644 msp_set_scart(client, sc2_out, 2);
645 msp_set_audmode(client);
646 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
647 val = msp_read_dem(client, reg);
648 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
649 /* wake thread when a new input is chosen */
650 msp_wake_thread(client); 621 msp_wake_thread(client);
651 break; 622 return 0;
623}
624
625static int msp_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
626{
627 struct msp_state *state = to_state(sd);
628 struct i2c_client *client = v4l2_get_subdevdata(sd);
629 int tuner = (rt->input >> 3) & 1;
630 int sc_in = rt->input & 0x7;
631 int sc1_out = rt->output & 0xf;
632 int sc2_out = (rt->output >> 4) & 0xf;
633 u16 val, reg;
634 int i;
635 int extern_input = 1;
636
637 if (state->routing.input == rt->input &&
638 state->routing.output == rt->output)
639 return 0;
640 state->routing = *rt;
641 /* check if the tuner input is used */
642 for (i = 0; i < 5; i++) {
643 if (((rt->input >> (4 + i * 4)) & 0xf) == 0)
644 extern_input = 0;
652 } 645 }
646 state->mode = extern_input ? MSP_MODE_EXTERN : MSP_MODE_AM_DETECT;
647 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
648 msp_set_scart(client, sc_in, 0);
649 msp_set_scart(client, sc1_out, 1);
650 msp_set_scart(client, sc2_out, 2);
651 msp_set_audmode(client);
652 reg = (state->opmode == OPMODE_AUTOSELECT) ? 0x30 : 0xbb;
653 val = msp_read_dem(client, reg);
654 msp_write_dem(client, reg, (val & ~0x100) | (tuner << 8));
655 /* wake thread when a new input is chosen */
656 msp_wake_thread(client);
657 return 0;
658}
653 659
654 case VIDIOC_G_TUNER: 660static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
655 { 661{
656 struct v4l2_tuner *vt = arg; 662 struct msp_state *state = to_state(sd);
663 struct i2c_client *client = v4l2_get_subdevdata(sd);
657 664
658 if (state->radio) 665 if (state->radio)
659 break; 666 return 0;
660 if (state->opmode == OPMODE_AUTOSELECT) 667 if (state->opmode == OPMODE_AUTOSELECT)
661 msp_detect_stereo(client); 668 msp_detect_stereo(client);
662 vt->audmode = state->audmode; 669 vt->audmode = state->audmode;
663 vt->rxsubchans = state->rxsubchans; 670 vt->rxsubchans = state->rxsubchans;
664 vt->capability |= V4L2_TUNER_CAP_STEREO | 671 vt->capability |= V4L2_TUNER_CAP_STEREO |
665 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 672 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
666 break; 673 return 0;
667 } 674}
668 675
669 case VIDIOC_S_TUNER: 676static int msp_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
670 { 677{
671 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 678 struct msp_state *state = to_state(sd);
679 struct i2c_client *client = v4l2_get_subdevdata(sd);
672 680
673 if (state->radio) /* TODO: add mono/stereo support for radio */ 681 if (state->radio) /* TODO: add mono/stereo support for radio */
674 break; 682 return 0;
675 if (state->audmode == vt->audmode) 683 if (state->audmode == vt->audmode)
676 break; 684 return 0;
677 state->audmode = vt->audmode; 685 state->audmode = vt->audmode;
678 /* only set audmode */ 686 /* only set audmode */
679 msp_set_audmode(client); 687 msp_set_audmode(client);
680 break; 688 return 0;
681 } 689}
682 690
683 case VIDIOC_INT_I2S_CLOCK_FREQ: 691static int msp_s_i2s_clock_freq(struct v4l2_subdev *sd, u32 freq)
684 { 692{
685 u32 *a = (u32 *)arg; 693 struct msp_state *state = to_state(sd);
694 struct i2c_client *client = v4l2_get_subdevdata(sd);
686 695
687 v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", *a); 696 v4l_dbg(1, msp_debug, client, "Setting I2S speed to %d\n", freq);
688 697
689 switch (*a) { 698 switch (freq) {
690 case 1024000: 699 case 1024000:
691 state->i2s_mode = 0; 700 state->i2s_mode = 0;
692 break; 701 break;
@@ -695,24 +704,24 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
695 break; 704 break;
696 default: 705 default:
697 return -EINVAL; 706 return -EINVAL;
698 }
699 break;
700 } 707 }
708 return 0;
709}
701 710
702 case VIDIOC_QUERYCTRL: 711static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
703 { 712{
704 struct v4l2_queryctrl *qc = arg; 713 struct msp_state *state = to_state(sd);
705 714
706 switch (qc->id) { 715 switch (qc->id) {
707 case V4L2_CID_AUDIO_VOLUME: 716 case V4L2_CID_AUDIO_VOLUME:
708 case V4L2_CID_AUDIO_MUTE: 717 case V4L2_CID_AUDIO_MUTE:
709 return v4l2_ctrl_query_fill_std(qc); 718 return v4l2_ctrl_query_fill_std(qc);
710 default: 719 default:
711 break; 720 break;
712 } 721 }
713 if (!state->has_sound_processing) 722 if (!state->has_sound_processing)
714 return -EINVAL; 723 return -EINVAL;
715 switch (qc->id) { 724 switch (qc->id) {
716 case V4L2_CID_AUDIO_LOUDNESS: 725 case V4L2_CID_AUDIO_LOUDNESS:
717 case V4L2_CID_AUDIO_BALANCE: 726 case V4L2_CID_AUDIO_BALANCE:
718 case V4L2_CID_AUDIO_BASS: 727 case V4L2_CID_AUDIO_BASS:
@@ -720,32 +729,38 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
720 return v4l2_ctrl_query_fill_std(qc); 729 return v4l2_ctrl_query_fill_std(qc);
721 default: 730 default:
722 return -EINVAL; 731 return -EINVAL;
723 }
724 } 732 }
733 return 0;
734}
725 735
726 case VIDIOC_G_CTRL: 736static int msp_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
727 return msp_get_ctrl(client, arg); 737{
728 738 struct msp_state *state = to_state(sd);
729 case VIDIOC_S_CTRL: 739 struct i2c_client *client = v4l2_get_subdevdata(sd);
730 return msp_set_ctrl(client, arg);
731 740
732 case VIDIOC_LOG_STATUS: 741 return v4l2_chip_ident_i2c_client(client, chip, state->ident,
733 { 742 (state->rev1 << 16) | state->rev2);
734 const char *p; 743}
735 744
736 if (state->opmode == OPMODE_AUTOSELECT) 745static int msp_log_status(struct v4l2_subdev *sd)
737 msp_detect_stereo(client); 746{
738 v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", 747 struct msp_state *state = to_state(sd);
739 client->name, state->rev1, state->rev2); 748 struct i2c_client *client = v4l2_get_subdevdata(sd);
740 v4l_info(client, "Audio: volume %d%s\n", 749 const char *p;
741 state->volume, state->muted ? " (muted)" : ""); 750
742 if (state->has_sound_processing) { 751 if (state->opmode == OPMODE_AUTOSELECT)
743 v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n", 752 msp_detect_stereo(client);
744 state->balance, state->bass, 753 v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n",
745 state->treble, 754 client->name, state->rev1, state->rev2);
746 state->loudness ? "on" : "off"); 755 v4l_info(client, "Audio: volume %d%s\n",
747 } 756 state->volume, state->muted ? " (muted)" : "");
748 switch (state->mode) { 757 if (state->has_sound_processing) {
758 v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n",
759 state->balance, state->bass,
760 state->treble,
761 state->loudness ? "on" : "off");
762 }
763 switch (state->mode) {
749 case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break; 764 case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break;
750 case MSP_MODE_FM_RADIO: p = "FM Radio"; break; 765 case MSP_MODE_FM_RADIO: p = "FM Radio"; break;
751 case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono/stereo"; break; 766 case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono/stereo"; break;
@@ -756,36 +771,25 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
756 case MSP_MODE_BTSC: p = "BTSC"; break; 771 case MSP_MODE_BTSC: p = "BTSC"; break;
757 case MSP_MODE_EXTERN: p = "External input"; break; 772 case MSP_MODE_EXTERN: p = "External input"; break;
758 default: p = "unknown"; break; 773 default: p = "unknown"; break;
759 } 774 }
760 if (state->mode == MSP_MODE_EXTERN) { 775 if (state->mode == MSP_MODE_EXTERN) {
761 v4l_info(client, "Mode: %s\n", p); 776 v4l_info(client, "Mode: %s\n", p);
762 } else if (state->opmode == OPMODE_MANUAL) { 777 } else if (state->opmode == OPMODE_MANUAL) {
763 v4l_info(client, "Mode: %s (%s%s)\n", p, 778 v4l_info(client, "Mode: %s (%s%s)\n", p,
764 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 779 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
765 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 780 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
766 } else { 781 } else {
767 if (state->opmode == OPMODE_AUTODETECT) 782 if (state->opmode == OPMODE_AUTODETECT)
768 v4l_info(client, "Mode: %s\n", p); 783 v4l_info(client, "Mode: %s\n", p);
769 v4l_info(client, "Standard: %s (%s%s)\n", 784 v4l_info(client, "Standard: %s (%s%s)\n",
770 msp_standard_std_name(state->std), 785 msp_standard_std_name(state->std),
771 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 786 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
772 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 787 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
773 }
774 v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
775 v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
776 state->routing.input, state->routing.output);
777 v4l_info(client, "ACB: 0x%04x\n", state->acb);
778 break;
779 }
780
781 case VIDIOC_G_CHIP_IDENT:
782 return v4l2_chip_ident_i2c_client(client, arg, state->ident,
783 (state->rev1 << 16) | state->rev2);
784
785 default:
786 /* unknown */
787 return -EINVAL;
788 } 788 }
789 v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
790 v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
791 state->routing.input, state->routing.output);
792 v4l_info(client, "ACB: 0x%04x\n", state->acb);
789 return 0; 793 return 0;
790} 794}
791 795
@@ -803,11 +807,49 @@ static int msp_resume(struct i2c_client *client)
803 return 0; 807 return 0;
804} 808}
805 809
810static int msp_command(struct i2c_client *client, unsigned cmd, void *arg)
811{
812 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
813}
814
815/* ----------------------------------------------------------------------- */
816
817static const struct v4l2_subdev_core_ops msp_core_ops = {
818 .log_status = msp_log_status,
819 .g_chip_ident = msp_g_chip_ident,
820 .g_ctrl = msp_g_ctrl,
821 .s_ctrl = msp_s_ctrl,
822 .queryctrl = msp_queryctrl,
823#ifdef CONFIG_VIDEO_ALLOW_V4L1
824 .ioctl = msp_ioctl,
825#endif
826};
827
828static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
829 .s_frequency = msp_s_frequency,
830 .g_tuner = msp_g_tuner,
831 .s_tuner = msp_s_tuner,
832 .s_radio = msp_s_radio,
833 .s_std = msp_s_std,
834};
835
836static const struct v4l2_subdev_audio_ops msp_audio_ops = {
837 .s_routing = msp_s_routing,
838 .s_i2s_clock_freq = msp_s_i2s_clock_freq,
839};
840
841static const struct v4l2_subdev_ops msp_ops = {
842 .core = &msp_core_ops,
843 .tuner = &msp_tuner_ops,
844 .audio = &msp_audio_ops,
845};
846
806/* ----------------------------------------------------------------------- */ 847/* ----------------------------------------------------------------------- */
807 848
808static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id) 849static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
809{ 850{
810 struct msp_state *state; 851 struct msp_state *state;
852 struct v4l2_subdev *sd;
811 int (*thread_func)(void *data) = NULL; 853 int (*thread_func)(void *data) = NULL;
812 int msp_hard; 854 int msp_hard;
813 int msp_family; 855 int msp_family;
@@ -827,7 +869,8 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
827 if (!state) 869 if (!state)
828 return -ENOMEM; 870 return -ENOMEM;
829 871
830 i2c_set_clientdata(client, state); 872 sd = &state->sd;
873 v4l2_i2c_subdev_init(sd, client, &msp_ops);
831 874
832 state->v4l2_std = V4L2_STD_NTSC; 875 state->v4l2_std = V4L2_STD_NTSC;
833 state->audmode = V4L2_TUNER_MODE_STEREO; 876 state->audmode = V4L2_TUNER_MODE_STEREO;
@@ -972,8 +1015,9 @@ static int msp_probe(struct i2c_client *client, const struct i2c_device_id *id)
972 1015
973static int msp_remove(struct i2c_client *client) 1016static int msp_remove(struct i2c_client *client)
974{ 1017{
975 struct msp_state *state = i2c_get_clientdata(client); 1018 struct msp_state *state = to_state(i2c_get_clientdata(client));
976 1019
1020 v4l2_device_unregister_subdev(&state->sd);
977 /* shutdown control thread */ 1021 /* shutdown control thread */
978 if (state->kthread) { 1022 if (state->kthread) {
979 state->restart = 1; 1023 state->restart = 1;
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index ab69a290e5dc..3fe1c1b10f53 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -5,6 +5,7 @@
5#define MSP3400_DRIVER_H 5#define MSP3400_DRIVER_H
6 6
7#include <media/msp3400.h> 7#include <media/msp3400.h>
8#include <media/v4l2-device.h>
8 9
9/* ---------------------------------------------------------------------- */ 10/* ---------------------------------------------------------------------- */
10 11
@@ -49,6 +50,7 @@ extern int msp_dolby;
49extern int msp_stereo_thresh; 50extern int msp_stereo_thresh;
50 51
51struct msp_state { 52struct msp_state {
53 struct v4l2_subdev sd;
52 int rev1, rev2; 54 int rev1, rev2;
53 int ident; 55 int ident;
54 u8 has_nicam; 56 u8 has_nicam;
@@ -96,6 +98,11 @@ struct msp_state {
96 unsigned int watch_stereo:1; 98 unsigned int watch_stereo:1;
97}; 99};
98 100
101static inline struct msp_state *to_state(struct v4l2_subdev *sd)
102{
103 return container_of(sd, struct msp_state, sd);
104}
105
99/* msp3400-driver.c */ 106/* msp3400-driver.c */
100int msp_write_dem(struct i2c_client *client, int addr, int val); 107int msp_write_dem(struct i2c_client *client, int addr, int val);
101int msp_write_dsp(struct i2c_client *client, int addr, int val); 108int msp_write_dsp(struct i2c_client *client, int addr, int val);
diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c
index 846a14a61fd1..a655e9c30146 100644
--- a/drivers/media/video/msp3400-kthreads.c
+++ b/drivers/media/video/msp3400-kthreads.c
@@ -159,7 +159,7 @@ const char *msp_standard_std_name(int std)
159 159
160static void msp_set_source(struct i2c_client *client, u16 src) 160static void msp_set_source(struct i2c_client *client, u16 src)
161{ 161{
162 struct msp_state *state = i2c_get_clientdata(client); 162 struct msp_state *state = to_state(i2c_get_clientdata(client));
163 163
164 if (msp_dolby) { 164 if (msp_dolby) {
165 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ 165 msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */
@@ -186,7 +186,7 @@ void msp3400c_set_carrier(struct i2c_client *client, int cdo1, int cdo2)
186 186
187void msp3400c_set_mode(struct i2c_client *client, int mode) 187void msp3400c_set_mode(struct i2c_client *client, int mode)
188{ 188{
189 struct msp_state *state = i2c_get_clientdata(client); 189 struct msp_state *state = to_state(i2c_get_clientdata(client));
190 struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode]; 190 struct msp3400c_init_data_dem *data = &msp3400c_init_data[mode];
191 int tuner = (state->routing.input >> 3) & 1; 191 int tuner = (state->routing.input >> 3) & 1;
192 int i; 192 int i;
@@ -227,7 +227,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
227 static char *strmode[] = { 227 static char *strmode[] = {
228 "mono", "stereo", "lang2", "lang1", "lang1+lang2" 228 "mono", "stereo", "lang2", "lang1", "lang1+lang2"
229 }; 229 };
230 struct msp_state *state = i2c_get_clientdata(client); 230 struct msp_state *state = to_state(i2c_get_clientdata(client));
231 char *modestr = (state->audmode >= 0 && state->audmode < 5) ? 231 char *modestr = (state->audmode >= 0 && state->audmode < 5) ?
232 strmode[state->audmode] : "unknown"; 232 strmode[state->audmode] : "unknown";
233 int src = 0; /* channel source: FM/AM, nicam or SCART */ 233 int src = 0; /* channel source: FM/AM, nicam or SCART */
@@ -356,7 +356,7 @@ static void msp3400c_set_audmode(struct i2c_client *client)
356 356
357static void msp3400c_print_mode(struct i2c_client *client) 357static void msp3400c_print_mode(struct i2c_client *client)
358{ 358{
359 struct msp_state *state = i2c_get_clientdata(client); 359 struct msp_state *state = to_state(i2c_get_clientdata(client));
360 360
361 if (state->main == state->second) 361 if (state->main == state->second)
362 v4l_dbg(1, msp_debug, client, 362 v4l_dbg(1, msp_debug, client,
@@ -385,7 +385,7 @@ static void msp3400c_print_mode(struct i2c_client *client)
385 385
386static int msp3400c_detect_stereo(struct i2c_client *client) 386static int msp3400c_detect_stereo(struct i2c_client *client)
387{ 387{
388 struct msp_state *state = i2c_get_clientdata(client); 388 struct msp_state *state = to_state(i2c_get_clientdata(client));
389 int val; 389 int val;
390 int rxsubchans = state->rxsubchans; 390 int rxsubchans = state->rxsubchans;
391 int newnicam = state->nicam_on; 391 int newnicam = state->nicam_on;
@@ -463,7 +463,7 @@ static int msp3400c_detect_stereo(struct i2c_client *client)
463/* stereo/multilang monitoring */ 463/* stereo/multilang monitoring */
464static void watch_stereo(struct i2c_client *client) 464static void watch_stereo(struct i2c_client *client)
465{ 465{
466 struct msp_state *state = i2c_get_clientdata(client); 466 struct msp_state *state = to_state(i2c_get_clientdata(client));
467 467
468 if (msp_detect_stereo(client)) 468 if (msp_detect_stereo(client))
469 msp_set_audmode(client); 469 msp_set_audmode(client);
@@ -475,7 +475,7 @@ static void watch_stereo(struct i2c_client *client)
475int msp3400c_thread(void *data) 475int msp3400c_thread(void *data)
476{ 476{
477 struct i2c_client *client = data; 477 struct i2c_client *client = data;
478 struct msp_state *state = i2c_get_clientdata(client); 478 struct msp_state *state = to_state(i2c_get_clientdata(client));
479 struct msp3400c_carrier_detect *cd; 479 struct msp3400c_carrier_detect *cd;
480 int count, max1, max2, val1, val2, val, i; 480 int count, max1, max2, val1, val2, val, i;
481 481
@@ -659,7 +659,7 @@ no_second:
659int msp3410d_thread(void *data) 659int msp3410d_thread(void *data)
660{ 660{
661 struct i2c_client *client = data; 661 struct i2c_client *client = data;
662 struct msp_state *state = i2c_get_clientdata(client); 662 struct msp_state *state = to_state(i2c_get_clientdata(client));
663 int val, i, std, count; 663 int val, i, std, count;
664 664
665 v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n"); 665 v4l_dbg(1, msp_debug, client, "msp3410 daemon started\n");
@@ -825,7 +825,7 @@ restart:
825 825
826static int msp34xxg_modus(struct i2c_client *client) 826static int msp34xxg_modus(struct i2c_client *client)
827{ 827{
828 struct msp_state *state = i2c_get_clientdata(client); 828 struct msp_state *state = to_state(i2c_get_clientdata(client));
829 829
830 if (state->radio) { 830 if (state->radio) {
831 v4l_dbg(1, msp_debug, client, "selected radio modus\n"); 831 v4l_dbg(1, msp_debug, client, "selected radio modus\n");
@@ -852,7 +852,7 @@ static int msp34xxg_modus(struct i2c_client *client)
852 852
853static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in) 853static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
854 { 854 {
855 struct msp_state *state = i2c_get_clientdata(client); 855 struct msp_state *state = to_state(i2c_get_clientdata(client));
856 int source, matrix; 856 int source, matrix;
857 857
858 switch (state->audmode) { 858 switch (state->audmode) {
@@ -895,7 +895,7 @@ static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
895 895
896static void msp34xxg_set_sources(struct i2c_client *client) 896static void msp34xxg_set_sources(struct i2c_client *client)
897{ 897{
898 struct msp_state *state = i2c_get_clientdata(client); 898 struct msp_state *state = to_state(i2c_get_clientdata(client));
899 u32 in = state->routing.input; 899 u32 in = state->routing.input;
900 900
901 msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf); 901 msp34xxg_set_source(client, 0x0008, (in >> 4) & 0xf);
@@ -911,7 +911,7 @@ static void msp34xxg_set_sources(struct i2c_client *client)
911/* (re-)initialize the msp34xxg */ 911/* (re-)initialize the msp34xxg */
912static void msp34xxg_reset(struct i2c_client *client) 912static void msp34xxg_reset(struct i2c_client *client)
913{ 913{
914 struct msp_state *state = i2c_get_clientdata(client); 914 struct msp_state *state = to_state(i2c_get_clientdata(client));
915 int tuner = (state->routing.input >> 3) & 1; 915 int tuner = (state->routing.input >> 3) & 1;
916 int modus; 916 int modus;
917 917
@@ -954,7 +954,7 @@ static void msp34xxg_reset(struct i2c_client *client)
954int msp34xxg_thread(void *data) 954int msp34xxg_thread(void *data)
955{ 955{
956 struct i2c_client *client = data; 956 struct i2c_client *client = data;
957 struct msp_state *state = i2c_get_clientdata(client); 957 struct msp_state *state = to_state(i2c_get_clientdata(client));
958 int val, i; 958 int val, i;
959 959
960 v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n"); 960 v4l_dbg(1, msp_debug, client, "msp34xxg daemon started\n");
@@ -1049,7 +1049,7 @@ unmute:
1049 1049
1050static int msp34xxg_detect_stereo(struct i2c_client *client) 1050static int msp34xxg_detect_stereo(struct i2c_client *client)
1051{ 1051{
1052 struct msp_state *state = i2c_get_clientdata(client); 1052 struct msp_state *state = to_state(i2c_get_clientdata(client));
1053 int status = msp_read_dem(client, 0x0200); 1053 int status = msp_read_dem(client, 0x0200);
1054 int is_bilingual = status & 0x100; 1054 int is_bilingual = status & 0x100;
1055 int is_stereo = status & 0x40; 1055 int is_stereo = status & 0x40;
@@ -1078,7 +1078,7 @@ static int msp34xxg_detect_stereo(struct i2c_client *client)
1078 1078
1079static void msp34xxg_set_audmode(struct i2c_client *client) 1079static void msp34xxg_set_audmode(struct i2c_client *client)
1080{ 1080{
1081 struct msp_state *state = i2c_get_clientdata(client); 1081 struct msp_state *state = to_state(i2c_get_clientdata(client));
1082 1082
1083 if (state->std == 0x20) { 1083 if (state->std == 0x20) {
1084 if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) && 1084 if ((state->rxsubchans & V4L2_TUNER_SUB_SAP) &&
@@ -1095,7 +1095,7 @@ static void msp34xxg_set_audmode(struct i2c_client *client)
1095 1095
1096void msp_set_audmode(struct i2c_client *client) 1096void msp_set_audmode(struct i2c_client *client)
1097{ 1097{
1098 struct msp_state *state = i2c_get_clientdata(client); 1098 struct msp_state *state = to_state(i2c_get_clientdata(client));
1099 1099
1100 switch (state->opmode) { 1100 switch (state->opmode) {
1101 case OPMODE_MANUAL: 1101 case OPMODE_MANUAL:
@@ -1110,7 +1110,7 @@ void msp_set_audmode(struct i2c_client *client)
1110 1110
1111int msp_detect_stereo(struct i2c_client *client) 1111int msp_detect_stereo(struct i2c_client *client)
1112{ 1112{
1113 struct msp_state *state = i2c_get_clientdata(client); 1113 struct msp_state *state = to_state(i2c_get_clientdata(client));
1114 1114
1115 switch (state->opmode) { 1115 switch (state->opmode) {
1116 case OPMODE_MANUAL: 1116 case OPMODE_MANUAL: