aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/msp3400-driver.c
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 /drivers/media/video/msp3400-driver.c
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>
Diffstat (limited to 'drivers/media/video/msp3400-driver.c')
-rw-r--r--drivers/media/video/msp3400-driver.c402
1 files changed, 223 insertions, 179 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 3da74dcee90..79ae7bd2352 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;