aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa717x.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-11-29 10:57:44 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:41 -0500
commit27760fc4b9b71d04568580fd44b38ac708731b28 (patch)
tree6586715317e983c1b58b782624ee1b3348f0dc70 /drivers/media/video/saa717x.c
parent627426c67553e2fbf99b5143623bffcc6b0b1020 (diff)
V4L/DVB (9828): saa717x: 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/saa717x.c')
-rw-r--r--drivers/media/video/saa717x.c610
1 files changed, 313 insertions, 297 deletions
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index af60ede5310d..9befca65905e 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -37,7 +37,7 @@
37 37
38#include <linux/videodev2.h> 38#include <linux/videodev2.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <media/v4l2-common.h> 40#include <media/v4l2-device.h>
41#include <media/v4l2-i2c-drv.h> 41#include <media/v4l2-i2c-drv.h>
42 42
43MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver"); 43MODULE_DESCRIPTION("Philips SAA717x audio/video decoder driver");
@@ -54,6 +54,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
54 */ 54 */
55 55
56struct saa717x_state { 56struct saa717x_state {
57 struct v4l2_subdev sd;
57 v4l2_std_id std; 58 v4l2_std_id std;
58 int input; 59 int input;
59 int enable; 60 int enable;
@@ -75,6 +76,11 @@ struct saa717x_state {
75 int audio_input; 76 int audio_input;
76}; 77};
77 78
79static inline struct saa717x_state *to_state(struct v4l2_subdev *sd)
80{
81 return container_of(sd, struct saa717x_state, sd);
82}
83
78/* ----------------------------------------------------------------------- */ 84/* ----------------------------------------------------------------------- */
79 85
80/* for audio mode */ 86/* for audio mode */
@@ -88,8 +94,9 @@ struct saa717x_state {
88 94
89/* ----------------------------------------------------------------------- */ 95/* ----------------------------------------------------------------------- */
90 96
91static int saa717x_write(struct i2c_client *client, u32 reg, u32 value) 97static int saa717x_write(struct v4l2_subdev *sd, u32 reg, u32 value)
92{ 98{
99 struct i2c_client *client = v4l2_get_subdevdata(sd);
93 struct i2c_adapter *adap = client->adapter; 100 struct i2c_adapter *adap = client->adapter;
94 int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488; 101 int fw_addr = reg == 0x454 || (reg >= 0x464 && reg <= 0x478) || reg == 0x480 || reg == 0x488;
95 unsigned char mm1[6]; 102 unsigned char mm1[6];
@@ -109,20 +116,21 @@ static int saa717x_write(struct i2c_client *client, u32 reg, u32 value)
109 } 116 }
110 msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */ 117 msg.len = fw_addr ? 5 : 3; /* Long Registers have *only* three bytes! */
111 msg.buf = mm1; 118 msg.buf = mm1;
112 v4l_dbg(2, debug, client, "wrote: reg 0x%03x=%08x\n", reg, value); 119 v4l2_dbg(2, debug, sd, "wrote: reg 0x%03x=%08x\n", reg, value);
113 return i2c_transfer(adap, &msg, 1) == 1; 120 return i2c_transfer(adap, &msg, 1) == 1;
114} 121}
115 122
116static void saa717x_write_regs(struct i2c_client *client, u32 *data) 123static void saa717x_write_regs(struct v4l2_subdev *sd, u32 *data)
117{ 124{
118 while (data[0] || data[1]) { 125 while (data[0] || data[1]) {
119 saa717x_write(client, data[0], data[1]); 126 saa717x_write(sd, data[0], data[1]);
120 data += 2; 127 data += 2;
121 } 128 }
122} 129}
123 130
124static u32 saa717x_read(struct i2c_client *client, u32 reg) 131static u32 saa717x_read(struct v4l2_subdev *sd, u32 reg)
125{ 132{
133 struct i2c_client *client = v4l2_get_subdevdata(sd);
126 struct i2c_adapter *adap = client->adapter; 134 struct i2c_adapter *adap = client->adapter;
127 int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528; 135 int fw_addr = (reg >= 0x404 && reg <= 0x4b8) || reg == 0x528;
128 unsigned char mm1[2]; 136 unsigned char mm1[2];
@@ -146,7 +154,7 @@ static u32 saa717x_read(struct i2c_client *client, u32 reg)
146 else 154 else
147 value = mm2[0] & 0xff; 155 value = mm2[0] & 0xff;
148 156
149 v4l_dbg(2, debug, client, "read: reg 0x%03x=0x%08x\n", reg, value); 157 v4l2_dbg(2, debug, sd, "read: reg 0x%03x=0x%08x\n", reg, value);
150 return value; 158 return value;
151} 159}
152 160
@@ -680,7 +688,7 @@ static u32 reg_set_audio_template[4][2] =
680 688
681 689
682/* Get detected audio flags (from saa7134 driver) */ 690/* Get detected audio flags (from saa7134 driver) */
683static void get_inf_dev_status(struct i2c_client *client, 691static void get_inf_dev_status(struct v4l2_subdev *sd,
684 int *dual_flag, int *stereo_flag) 692 int *dual_flag, int *stereo_flag)
685{ 693{
686 u32 reg_data3; 694 u32 reg_data3;
@@ -719,13 +727,13 @@ static void get_inf_dev_status(struct i2c_client *client,
719 /* (demdec status: 0x528) */ 727 /* (demdec status: 0x528) */
720 728
721 /* read current status */ 729 /* read current status */
722 reg_data3 = saa717x_read(client, 0x0528); 730 reg_data3 = saa717x_read(sd, 0x0528);
723 731
724 v4l_dbg(1, debug, client, "tvaudio thread status: 0x%x [%s%s%s]\n", 732 v4l2_dbg(1, debug, sd, "tvaudio thread status: 0x%x [%s%s%s]\n",
725 reg_data3, stdres[reg_data3 & 0x1f], 733 reg_data3, stdres[reg_data3 & 0x1f],
726 (reg_data3 & 0x000020) ? ",stereo" : "", 734 (reg_data3 & 0x000020) ? ",stereo" : "",
727 (reg_data3 & 0x000040) ? ",dual" : ""); 735 (reg_data3 & 0x000040) ? ",dual" : "");
728 v4l_dbg(1, debug, client, "detailed status: " 736 v4l2_dbg(1, debug, sd, "detailed status: "
729 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n", 737 "%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s#%s\n",
730 (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "", 738 (reg_data3 & 0x000080) ? " A2/EIAJ pilot tone " : "",
731 (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "", 739 (reg_data3 & 0x000100) ? " A2/EIAJ dual " : "",
@@ -746,51 +754,51 @@ static void get_inf_dev_status(struct i2c_client *client,
746 (reg_data3 & 0x100000) ? " init done " : ""); 754 (reg_data3 & 0x100000) ? " init done " : "");
747 755
748 if (reg_data3 & 0x000220) { 756 if (reg_data3 & 0x000220) {
749 v4l_dbg(1, debug, client, "ST!!!\n"); 757 v4l2_dbg(1, debug, sd, "ST!!!\n");
750 *stereo_flag = 1; 758 *stereo_flag = 1;
751 } 759 }
752 760
753 if (reg_data3 & 0x000140) { 761 if (reg_data3 & 0x000140) {
754 v4l_dbg(1, debug, client, "DUAL!!!\n"); 762 v4l2_dbg(1, debug, sd, "DUAL!!!\n");
755 *dual_flag = 1; 763 *dual_flag = 1;
756 } 764 }
757} 765}
758 766
759/* regs write to set audio mode */ 767/* regs write to set audio mode */
760static void set_audio_mode(struct i2c_client *client, int audio_mode) 768static void set_audio_mode(struct v4l2_subdev *sd, int audio_mode)
761{ 769{
762 v4l_dbg(1, debug, client, "writing registers to set audio mode by set %d\n", 770 v4l2_dbg(1, debug, sd, "writing registers to set audio mode by set %d\n",
763 audio_mode); 771 audio_mode);
764 772
765 saa717x_write(client, 0x46c, reg_set_audio_template[audio_mode][0]); 773 saa717x_write(sd, 0x46c, reg_set_audio_template[audio_mode][0]);
766 saa717x_write(client, 0x470, reg_set_audio_template[audio_mode][1]); 774 saa717x_write(sd, 0x470, reg_set_audio_template[audio_mode][1]);
767} 775}
768 776
769/* write regs to video output level (bright,contrast,hue,sat) */ 777/* write regs to video output level (bright,contrast,hue,sat) */
770static void set_video_output_level_regs(struct i2c_client *client, 778static void set_video_output_level_regs(struct v4l2_subdev *sd,
771 struct saa717x_state *decoder) 779 struct saa717x_state *decoder)
772{ 780{
773 /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */ 781 /* brightness ffh (bright) - 80h (ITU level) - 00h (dark) */
774 saa717x_write(client, 0x10a, decoder->bright); 782 saa717x_write(sd, 0x10a, decoder->bright);
775 783
776 /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) - 784 /* contrast 7fh (max: 1.984) - 44h (ITU) - 40h (1.0) -
777 0h (luminance off) 40: i2c dump 785 0h (luminance off) 40: i2c dump
778 c0h (-1.0 inverse chrominance) 786 c0h (-1.0 inverse chrominance)
779 80h (-2.0 inverse chrominance) */ 787 80h (-2.0 inverse chrominance) */
780 saa717x_write(client, 0x10b, decoder->contrast); 788 saa717x_write(sd, 0x10b, decoder->contrast);
781 789
782 /* saturation? 7fh(max)-40h(ITU)-0h(color off) 790 /* saturation? 7fh(max)-40h(ITU)-0h(color off)
783 c0h (-1.0 inverse chrominance) 791 c0h (-1.0 inverse chrominance)
784 80h (-2.0 inverse chrominance) */ 792 80h (-2.0 inverse chrominance) */
785 saa717x_write(client, 0x10c, decoder->sat); 793 saa717x_write(sd, 0x10c, decoder->sat);
786 794
787 /* color hue (phase) control 795 /* color hue (phase) control
788 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */ 796 7fh (+178.6) - 0h (0 normal) - 80h (-180.0) */
789 saa717x_write(client, 0x10d, decoder->hue); 797 saa717x_write(sd, 0x10d, decoder->hue);
790} 798}
791 799
792/* write regs to set audio volume, bass and treble */ 800/* write regs to set audio volume, bass and treble */
793static int set_audio_regs(struct i2c_client *client, 801static int set_audio_regs(struct v4l2_subdev *sd,
794 struct saa717x_state *decoder) 802 struct saa717x_state *decoder)
795{ 803{
796 u8 mute = 0xac; /* -84 dB */ 804 u8 mute = 0xac; /* -84 dB */
@@ -798,8 +806,8 @@ static int set_audio_regs(struct i2c_client *client,
798 unsigned int work_l, work_r; 806 unsigned int work_l, work_r;
799 807
800 /* set SIF analog I/O select */ 808 /* set SIF analog I/O select */
801 saa717x_write(client, 0x0594, decoder->audio_input); 809 saa717x_write(sd, 0x0594, decoder->audio_input);
802 v4l_dbg(1, debug, client, "set audio input %d\n", 810 v4l2_dbg(1, debug, sd, "set audio input %d\n",
803 decoder->audio_input); 811 decoder->audio_input);
804 812
805 /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */ 813 /* normalize ( 65535 to 0 -> 24 to -40 (not -84)) */
@@ -819,17 +827,17 @@ static int set_audio_regs(struct i2c_client *client,
819 ((u8)decoder->audio_main_vol_r << 8); 827 ((u8)decoder->audio_main_vol_r << 8);
820 } 828 }
821 829
822 saa717x_write(client, 0x480, val); 830 saa717x_write(sd, 0x480, val);
823 831
824 /* bass and treble; go to another function */ 832 /* bass and treble; go to another function */
825 /* set bass and treble */ 833 /* set bass and treble */
826 val = decoder->audio_main_bass | (decoder->audio_main_treble << 8); 834 val = decoder->audio_main_bass | (decoder->audio_main_treble << 8);
827 saa717x_write(client, 0x488, val); 835 saa717x_write(sd, 0x488, val);
828 return 0; 836 return 0;
829} 837}
830 838
831/********** scaling staff ***********/ 839/********** scaling staff ***********/
832static void set_h_prescale(struct i2c_client *client, 840static void set_h_prescale(struct v4l2_subdev *sd,
833 int task, int prescale) 841 int task, int prescale)
834{ 842{
835 static const struct { 843 static const struct {
@@ -862,107 +870,101 @@ static void set_h_prescale(struct i2c_client *client,
862 return; 870 return;
863 871
864 /* horizonal prescaling */ 872 /* horizonal prescaling */
865 saa717x_write(client, 0x60 + task_shift, vals[i].xpsc); 873 saa717x_write(sd, 0x60 + task_shift, vals[i].xpsc);
866 /* accumulation length */ 874 /* accumulation length */
867 saa717x_write(client, 0x61 + task_shift, vals[i].xacl); 875 saa717x_write(sd, 0x61 + task_shift, vals[i].xacl);
868 /* level control */ 876 /* level control */
869 saa717x_write(client, 0x62 + task_shift, 877 saa717x_write(sd, 0x62 + task_shift,
870 (vals[i].xc2_1 << 3) | vals[i].xdcg); 878 (vals[i].xc2_1 << 3) | vals[i].xdcg);
871 /*FIR prefilter control */ 879 /*FIR prefilter control */
872 saa717x_write(client, 0x63 + task_shift, 880 saa717x_write(sd, 0x63 + task_shift,
873 (vals[i].vpfy << 2) | vals[i].vpfy); 881 (vals[i].vpfy << 2) | vals[i].vpfy);
874} 882}
875 883
876/********** scaling staff ***********/ 884/********** scaling staff ***********/
877static void set_v_scale(struct i2c_client *client, int task, int yscale) 885static void set_v_scale(struct v4l2_subdev *sd, int task, int yscale)
878{ 886{
879 int task_shift; 887 int task_shift;
880 888
881 task_shift = task * 0x40; 889 task_shift = task * 0x40;
882 /* Vertical scaling ratio (LOW) */ 890 /* Vertical scaling ratio (LOW) */
883 saa717x_write(client, 0x70 + task_shift, yscale & 0xff); 891 saa717x_write(sd, 0x70 + task_shift, yscale & 0xff);
884 /* Vertical scaling ratio (HI) */ 892 /* Vertical scaling ratio (HI) */
885 saa717x_write(client, 0x71 + task_shift, yscale >> 8); 893 saa717x_write(sd, 0x71 + task_shift, yscale >> 8);
886}
887
888static int saa717x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
889{
890 /* not yet implament, so saa717x_cfg_??hz_??_audio is not defined. */
891 return 0;
892} 894}
893 895
894static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 896static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
895{ 897{
896 struct saa717x_state *state = i2c_get_clientdata(client); 898 struct saa717x_state *state = to_state(sd);
897 899
898 switch (ctrl->id) { 900 switch (ctrl->id) {
899 case V4L2_CID_BRIGHTNESS: 901 case V4L2_CID_BRIGHTNESS:
900 if (ctrl->value < 0 || ctrl->value > 255) { 902 if (ctrl->value < 0 || ctrl->value > 255) {
901 v4l_err(client, "invalid brightness setting %d\n", ctrl->value); 903 v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value);
902 return -ERANGE; 904 return -ERANGE;
903 } 905 }
904 906
905 state->bright = ctrl->value; 907 state->bright = ctrl->value;
906 v4l_dbg(1, debug, client, "bright:%d\n", state->bright); 908 v4l2_dbg(1, debug, sd, "bright:%d\n", state->bright);
907 saa717x_write(client, 0x10a, state->bright); 909 saa717x_write(sd, 0x10a, state->bright);
908 break; 910 break;
909 911
910 case V4L2_CID_CONTRAST: 912 case V4L2_CID_CONTRAST:
911 if (ctrl->value < 0 || ctrl->value > 127) { 913 if (ctrl->value < 0 || ctrl->value > 127) {
912 v4l_err(client, "invalid contrast setting %d\n", ctrl->value); 914 v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value);
913 return -ERANGE; 915 return -ERANGE;
914 } 916 }
915 917
916 state->contrast = ctrl->value; 918 state->contrast = ctrl->value;
917 v4l_dbg(1, debug, client, "contrast:%d\n", state->contrast); 919 v4l2_dbg(1, debug, sd, "contrast:%d\n", state->contrast);
918 saa717x_write(client, 0x10b, state->contrast); 920 saa717x_write(sd, 0x10b, state->contrast);
919 break; 921 break;
920 922
921 case V4L2_CID_SATURATION: 923 case V4L2_CID_SATURATION:
922 if (ctrl->value < 0 || ctrl->value > 127) { 924 if (ctrl->value < 0 || ctrl->value > 127) {
923 v4l_err(client, "invalid saturation setting %d\n", ctrl->value); 925 v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value);
924 return -ERANGE; 926 return -ERANGE;
925 } 927 }
926 928
927 state->sat = ctrl->value; 929 state->sat = ctrl->value;
928 v4l_dbg(1, debug, client, "sat:%d\n", state->sat); 930 v4l2_dbg(1, debug, sd, "sat:%d\n", state->sat);
929 saa717x_write(client, 0x10c, state->sat); 931 saa717x_write(sd, 0x10c, state->sat);
930 break; 932 break;
931 933
932 case V4L2_CID_HUE: 934 case V4L2_CID_HUE:
933 if (ctrl->value < -127 || ctrl->value > 127) { 935 if (ctrl->value < -127 || ctrl->value > 127) {
934 v4l_err(client, "invalid hue setting %d\n", ctrl->value); 936 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
935 return -ERANGE; 937 return -ERANGE;
936 } 938 }
937 939
938 state->hue = ctrl->value; 940 state->hue = ctrl->value;
939 v4l_dbg(1, debug, client, "hue:%d\n", state->hue); 941 v4l2_dbg(1, debug, sd, "hue:%d\n", state->hue);
940 saa717x_write(client, 0x10d, state->hue); 942 saa717x_write(sd, 0x10d, state->hue);
941 break; 943 break;
942 944
943 case V4L2_CID_AUDIO_MUTE: 945 case V4L2_CID_AUDIO_MUTE:
944 state->audio_main_mute = ctrl->value; 946 state->audio_main_mute = ctrl->value;
945 set_audio_regs(client, state); 947 set_audio_regs(sd, state);
946 break; 948 break;
947 949
948 case V4L2_CID_AUDIO_VOLUME: 950 case V4L2_CID_AUDIO_VOLUME:
949 state->audio_main_volume = ctrl->value; 951 state->audio_main_volume = ctrl->value;
950 set_audio_regs(client, state); 952 set_audio_regs(sd, state);
951 break; 953 break;
952 954
953 case V4L2_CID_AUDIO_BALANCE: 955 case V4L2_CID_AUDIO_BALANCE:
954 state->audio_main_balance = ctrl->value; 956 state->audio_main_balance = ctrl->value;
955 set_audio_regs(client, state); 957 set_audio_regs(sd, state);
956 break; 958 break;
957 959
958 case V4L2_CID_AUDIO_TREBLE: 960 case V4L2_CID_AUDIO_TREBLE:
959 state->audio_main_treble = ctrl->value; 961 state->audio_main_treble = ctrl->value;
960 set_audio_regs(client, state); 962 set_audio_regs(sd, state);
961 break; 963 break;
962 964
963 case V4L2_CID_AUDIO_BASS: 965 case V4L2_CID_AUDIO_BASS:
964 state->audio_main_bass = ctrl->value; 966 state->audio_main_bass = ctrl->value;
965 set_audio_regs(client, state); 967 set_audio_regs(sd, state);
966 break; 968 break;
967 969
968 default: 970 default:
@@ -972,9 +974,9 @@ static int saa717x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
972 return 0; 974 return 0;
973} 975}
974 976
975static int saa717x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 977static int saa717x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
976{ 978{
977 struct saa717x_state *state = i2c_get_clientdata(client); 979 struct saa717x_state *state = to_state(sd);
978 980
979 switch (ctrl->id) { 981 switch (ctrl->id) {
980 case V4L2_CID_BRIGHTNESS: 982 case V4L2_CID_BRIGHTNESS:
@@ -1103,13 +1105,15 @@ static struct v4l2_queryctrl saa717x_qctrl[] = {
1103 }, 1105 },
1104}; 1106};
1105 1107
1106static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_state *decoder, int inp) 1108static int saa717x_s_video_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1107{ 1109{
1110 struct saa717x_state *decoder = to_state(sd);
1111 int inp = route->input;
1108 int is_tuner = inp & 0x80; /* tuner input flag */ 1112 int is_tuner = inp & 0x80; /* tuner input flag */
1109 1113
1110 inp &= 0x7f; 1114 inp &= 0x7f;
1111 1115
1112 v4l_dbg(1, debug, client, "decoder set input (%d)\n", inp); 1116 v4l2_dbg(1, debug, sd, "decoder set input (%d)\n", inp);
1113 /* inputs from 0-9 are available*/ 1117 /* inputs from 0-9 are available*/
1114 /* saa717x have mode0-mode9 but mode5 is reserved. */ 1118 /* saa717x have mode0-mode9 but mode5 is reserved. */
1115 if (inp < 0 || inp > 9 || inp == 5) 1119 if (inp < 0 || inp > 9 || inp == 5)
@@ -1119,222 +1123,197 @@ static int saa717x_set_video_input(struct i2c_client *client, struct saa717x_sta
1119 int input_line = inp; 1123 int input_line = inp;
1120 1124
1121 decoder->input = input_line; 1125 decoder->input = input_line;
1122 v4l_dbg(1, debug, client, "now setting %s input %d\n", 1126 v4l2_dbg(1, debug, sd, "now setting %s input %d\n",
1123 input_line >= 6 ? "S-Video" : "Composite", 1127 input_line >= 6 ? "S-Video" : "Composite",
1124 input_line); 1128 input_line);
1125 1129
1126 /* select mode */ 1130 /* select mode */
1127 saa717x_write(client, 0x102, 1131 saa717x_write(sd, 0x102,
1128 (saa717x_read(client, 0x102) & 0xf0) | 1132 (saa717x_read(sd, 0x102) & 0xf0) |
1129 input_line); 1133 input_line);
1130 1134
1131 /* bypass chrominance trap for modes 6..9 */ 1135 /* bypass chrominance trap for modes 6..9 */
1132 saa717x_write(client, 0x109, 1136 saa717x_write(sd, 0x109,
1133 (saa717x_read(client, 0x109) & 0x7f) | 1137 (saa717x_read(sd, 0x109) & 0x7f) |
1134 (input_line < 6 ? 0x0 : 0x80)); 1138 (input_line < 6 ? 0x0 : 0x80));
1135 1139
1136 /* change audio_mode */ 1140 /* change audio_mode */
1137 if (is_tuner) { 1141 if (is_tuner) {
1138 /* tuner */ 1142 /* tuner */
1139 set_audio_mode(client, decoder->tuner_audio_mode); 1143 set_audio_mode(sd, decoder->tuner_audio_mode);
1140 } else { 1144 } else {
1141 /* Force to STEREO mode if Composite or 1145 /* Force to STEREO mode if Composite or
1142 * S-Video were chosen */ 1146 * S-Video were chosen */
1143 set_audio_mode(client, TUNER_AUDIO_STEREO); 1147 set_audio_mode(sd, TUNER_AUDIO_STEREO);
1144 } 1148 }
1145 /* change initialize procedure (Composite/S-Video) */ 1149 /* change initialize procedure (Composite/S-Video) */
1146 if (is_tuner) 1150 if (is_tuner)
1147 saa717x_write_regs(client, reg_init_tuner_input); 1151 saa717x_write_regs(sd, reg_init_tuner_input);
1148 else if (input_line >= 6) 1152 else if (input_line >= 6)
1149 saa717x_write_regs(client, reg_init_svideo_input); 1153 saa717x_write_regs(sd, reg_init_svideo_input);
1150 else 1154 else
1151 saa717x_write_regs(client, reg_init_composite_input); 1155 saa717x_write_regs(sd, reg_init_composite_input);
1152 } 1156 }
1153 1157
1154 return 0; 1158 return 0;
1155} 1159}
1156 1160
1157static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg) 1161static int saa717x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1158{ 1162{
1159 struct saa717x_state *decoder = i2c_get_clientdata(client); 1163 int i;
1160
1161 v4l_dbg(1, debug, client, "IOCTL: %08x\n", cmd);
1162 1164
1163 switch (cmd) { 1165 for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++)
1164 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1166 if (qc->id && qc->id == saa717x_qctrl[i].id) {
1165 return saa717x_set_audio_clock_freq(client, *(u32 *)arg); 1167 memcpy(qc, &saa717x_qctrl[i], sizeof(*qc));
1168 return 0;
1169 }
1170 return -EINVAL;
1171}
1166 1172
1167 case VIDIOC_G_CTRL: 1173#ifdef CONFIG_VIDEO_ADV_DEBUG
1168 return saa717x_get_v4lctrl(client, (struct v4l2_control *)arg); 1174static int saa717x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1175{
1176 struct i2c_client *client = v4l2_get_subdevdata(sd);
1169 1177
1170 case VIDIOC_S_CTRL: 1178 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1171 return saa717x_set_v4lctrl(client, (struct v4l2_control *)arg); 1179 return -EINVAL;
1180 if (!capable(CAP_SYS_ADMIN))
1181 return -EPERM;
1182 reg->val = saa717x_read(sd, reg->reg);
1183 return 0;
1184}
1172 1185
1173 case VIDIOC_QUERYCTRL: { 1186static int saa717x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1174 struct v4l2_queryctrl *qc = arg; 1187{
1175 int i; 1188 struct i2c_client *client = v4l2_get_subdevdata(sd);
1189 u16 addr = reg->reg & 0xffff;
1190 u8 val = reg->val & 0xff;
1176 1191
1177 for (i = 0; i < ARRAY_SIZE(saa717x_qctrl); i++) 1192 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1178 if (qc->id && qc->id == saa717x_qctrl[i].id) {
1179 memcpy(qc, &saa717x_qctrl[i], sizeof(*qc));
1180 return 0;
1181 }
1182 return -EINVAL; 1193 return -EINVAL;
1183 } 1194 if (!capable(CAP_SYS_ADMIN))
1184 1195 return -EPERM;
1185#ifdef CONFIG_VIDEO_ADV_DEBUG 1196 saa717x_write(sd, addr, val);
1186 case VIDIOC_DBG_G_REGISTER: { 1197 return 0;
1187 struct v4l2_register *reg = arg; 1198}
1188 1199#endif
1189 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip))
1190 return -EINVAL;
1191 if (!capable(CAP_SYS_ADMIN))
1192 return -EPERM;
1193 reg->val = saa717x_read(client, reg->reg);
1194 break;
1195 }
1196 1200
1197 case VIDIOC_DBG_S_REGISTER: { 1201static int saa717x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1198 struct v4l2_register *reg = arg; 1202{
1199 u16 addr = reg->reg & 0xffff; 1203 struct v4l2_pix_format *pix;
1200 u8 val = reg->val & 0xff; 1204 int prescale, h_scale, v_scale;
1201 1205
1202 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) 1206 pix = &fmt->fmt.pix;
1203 return -EINVAL; 1207 v4l2_dbg(1, debug, sd, "decoder set size\n");
1204 if (!capable(CAP_SYS_ADMIN))
1205 return -EPERM;
1206 saa717x_write(client, addr, val);
1207 break;
1208 }
1209#endif
1210 1208
1211 case VIDIOC_S_FMT: { 1209 /* FIXME need better bounds checking here */
1212 struct v4l2_format *fmt = (struct v4l2_format *)arg; 1210 if (pix->width < 1 || pix->width > 1440)
1213 struct v4l2_pix_format *pix; 1211 return -EINVAL;
1214 int prescale, h_scale, v_scale; 1212 if (pix->height < 1 || pix->height > 960)
1215 1213 return -EINVAL;
1216 pix = &fmt->fmt.pix;
1217 v4l_dbg(1, debug, client, "decoder set size\n");
1218
1219 /* FIXME need better bounds checking here */
1220 if (pix->width < 1 || pix->width > 1440)
1221 return -EINVAL;
1222 if (pix->height < 1 || pix->height > 960)
1223 return -EINVAL;
1224
1225 /* scaling setting */
1226 /* NTSC and interlace only */
1227 prescale = SAA717X_NTSC_WIDTH / pix->width;
1228 if (prescale == 0)
1229 prescale = 1;
1230 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width;
1231 /* interlace */
1232 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height;
1233
1234 /* Horizontal prescaling etc */
1235 set_h_prescale(client, 0, prescale);
1236 set_h_prescale(client, 1, prescale);
1237
1238 /* Horizontal scaling increment */
1239 /* TASK A */
1240 saa717x_write(client, 0x6C, (u8)(h_scale & 0xFF));
1241 saa717x_write(client, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1242 /* TASK B */
1243 saa717x_write(client, 0xAC, (u8)(h_scale & 0xFF));
1244 saa717x_write(client, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1245
1246 /* Vertical prescaling etc */
1247 set_v_scale(client, 0, v_scale);
1248 set_v_scale(client, 1, v_scale);
1249
1250 /* set video output size */
1251 /* video number of pixels at output */
1252 /* TASK A */
1253 saa717x_write(client, 0x5C, (u8)(pix->width & 0xFF));
1254 saa717x_write(client, 0x5D, (u8)((pix->width >> 8) & 0xFF));
1255 /* TASK B */
1256 saa717x_write(client, 0x9C, (u8)(pix->width & 0xFF));
1257 saa717x_write(client, 0x9D, (u8)((pix->width >> 8) & 0xFF));
1258
1259 /* video number of lines at output */
1260 /* TASK A */
1261 saa717x_write(client, 0x5E, (u8)(pix->height & 0xFF));
1262 saa717x_write(client, 0x5F, (u8)((pix->height >> 8) & 0xFF));
1263 /* TASK B */
1264 saa717x_write(client, 0x9E, (u8)(pix->height & 0xFF));
1265 saa717x_write(client, 0x9F, (u8)((pix->height >> 8) & 0xFF));
1266 break;
1267 }
1268 1214
1269 case AUDC_SET_RADIO: 1215 /* scaling setting */
1270 decoder->radio = 1; 1216 /* NTSC and interlace only */
1271 break; 1217 prescale = SAA717X_NTSC_WIDTH / pix->width;
1218 if (prescale == 0)
1219 prescale = 1;
1220 h_scale = 1024 * SAA717X_NTSC_WIDTH / prescale / pix->width;
1221 /* interlace */
1222 v_scale = 512 * 2 * SAA717X_NTSC_HEIGHT / pix->height;
1223
1224 /* Horizontal prescaling etc */
1225 set_h_prescale(sd, 0, prescale);
1226 set_h_prescale(sd, 1, prescale);
1227
1228 /* Horizontal scaling increment */
1229 /* TASK A */
1230 saa717x_write(sd, 0x6C, (u8)(h_scale & 0xFF));
1231 saa717x_write(sd, 0x6D, (u8)((h_scale >> 8) & 0xFF));
1232 /* TASK B */
1233 saa717x_write(sd, 0xAC, (u8)(h_scale & 0xFF));
1234 saa717x_write(sd, 0xAD, (u8)((h_scale >> 8) & 0xFF));
1235
1236 /* Vertical prescaling etc */
1237 set_v_scale(sd, 0, v_scale);
1238 set_v_scale(sd, 1, v_scale);
1239
1240 /* set video output size */
1241 /* video number of pixels at output */
1242 /* TASK A */
1243 saa717x_write(sd, 0x5C, (u8)(pix->width & 0xFF));
1244 saa717x_write(sd, 0x5D, (u8)((pix->width >> 8) & 0xFF));
1245 /* TASK B */
1246 saa717x_write(sd, 0x9C, (u8)(pix->width & 0xFF));
1247 saa717x_write(sd, 0x9D, (u8)((pix->width >> 8) & 0xFF));
1248
1249 /* video number of lines at output */
1250 /* TASK A */
1251 saa717x_write(sd, 0x5E, (u8)(pix->height & 0xFF));
1252 saa717x_write(sd, 0x5F, (u8)((pix->height >> 8) & 0xFF));
1253 /* TASK B */
1254 saa717x_write(sd, 0x9E, (u8)(pix->height & 0xFF));
1255 saa717x_write(sd, 0x9F, (u8)((pix->height >> 8) & 0xFF));
1256 return 0;
1257}
1272 1258
1273 case VIDIOC_S_STD: { 1259static int saa717x_s_radio(struct v4l2_subdev *sd)
1274 v4l2_std_id std = *(v4l2_std_id *) arg; 1260{
1261 struct saa717x_state *decoder = to_state(sd);
1275 1262
1276 v4l_dbg(1, debug, client, "decoder set norm "); 1263 decoder->radio = 1;
1277 v4l_dbg(1, debug, client, "(not yet implementd)\n"); 1264 return 0;
1265}
1278 1266
1279 decoder->radio = 0; 1267static int saa717x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1280 decoder->std = std; 1268{
1281 break; 1269 struct saa717x_state *decoder = to_state(sd);
1282 }
1283 1270
1284 case VIDIOC_INT_G_AUDIO_ROUTING: { 1271 v4l2_dbg(1, debug, sd, "decoder set norm ");
1285 struct v4l2_routing *route = arg; 1272 v4l2_dbg(1, debug, sd, "(not yet implementd)\n");
1286 1273
1287 route->input = decoder->audio_input; 1274 decoder->radio = 0;
1288 route->output = 0; 1275 decoder->std = std;
1289 break; 1276 return 0;
1290 } 1277}
1291 1278
1292 case VIDIOC_INT_S_AUDIO_ROUTING: { 1279static int saa717x_s_audio_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1293 struct v4l2_routing *route = arg; 1280{
1281 struct saa717x_state *decoder = to_state(sd);
1294 1282
1295 if (route->input < 3) { /* FIXME! --tadachi */ 1283 if (route->input < 3) { /* FIXME! --tadachi */
1296 decoder->audio_input = route->input; 1284 decoder->audio_input = route->input;
1297 v4l_dbg(1, debug, client, 1285 v4l2_dbg(1, debug, sd,
1298 "set decoder audio input to %d\n", 1286 "set decoder audio input to %d\n",
1299 decoder->audio_input); 1287 decoder->audio_input);
1300 set_audio_regs(client, decoder); 1288 set_audio_regs(sd, decoder);
1301 break; 1289 return 0;
1302 }
1303 return -ERANGE;
1304 }
1305
1306 case VIDIOC_INT_S_VIDEO_ROUTING: {
1307 struct v4l2_routing *route = arg;
1308 int inp = route->input;
1309
1310 return saa717x_set_video_input(client, decoder, inp);
1311 } 1290 }
1291 return -ERANGE;
1292}
1312 1293
1313 case VIDIOC_STREAMON: { 1294static int saa717x_s_stream(struct v4l2_subdev *sd, int enable)
1314 v4l_dbg(1, debug, client, "decoder enable output\n"); 1295{
1315 decoder->enable = 1; 1296 struct saa717x_state *decoder = to_state(sd);
1316 saa717x_write(client, 0x193, 0xa6);
1317 break;
1318 }
1319 1297
1320 case VIDIOC_STREAMOFF: { 1298 v4l2_dbg(1, debug, sd, "decoder %s output\n",
1321 v4l_dbg(1, debug, client, "decoder disable output\n"); 1299 enable ? "enable" : "disable");
1322 decoder->enable = 0; 1300 decoder->enable = enable;
1323 saa717x_write(client, 0x193, 0x26); /* right? FIXME!--tadachi */ 1301 saa717x_write(sd, 0x193, enable ? 0xa6 : 0x26);
1324 break; 1302 return 0;
1325 } 1303}
1326 1304
1327 /* change audio mode */ 1305/* change audio mode */
1328 case VIDIOC_S_TUNER: { 1306static int saa717x_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1329 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 1307{
1330 int audio_mode; 1308 struct saa717x_state *decoder = to_state(sd);
1331 char *mes[4] = { 1309 int audio_mode;
1332 "MONO", "STEREO", "LANG1", "LANG2/SAP" 1310 char *mes[4] = {
1333 }; 1311 "MONO", "STEREO", "LANG1", "LANG2/SAP"
1312 };
1334 1313
1335 audio_mode = V4L2_TUNER_MODE_STEREO; 1314 audio_mode = V4L2_TUNER_MODE_STEREO;
1336 1315
1337 switch (vt->audmode) { 1316 switch (vt->audmode) {
1338 case V4L2_TUNER_MODE_MONO: 1317 case V4L2_TUNER_MODE_MONO:
1339 audio_mode = TUNER_AUDIO_MONO; 1318 audio_mode = TUNER_AUDIO_MONO;
1340 break; 1319 break;
@@ -1347,70 +1326,101 @@ static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
1347 case V4L2_TUNER_MODE_LANG1: 1326 case V4L2_TUNER_MODE_LANG1:
1348 audio_mode = TUNER_AUDIO_LANG1; 1327 audio_mode = TUNER_AUDIO_LANG1;
1349 break; 1328 break;
1350 }
1351
1352 v4l_dbg(1, debug, client, "change audio mode to %s\n",
1353 mes[audio_mode]);
1354 decoder->tuner_audio_mode = audio_mode;
1355 /* The registers are not changed here. */
1356 /* See DECODER_ENABLE_OUTPUT section. */
1357 set_audio_mode(client, decoder->tuner_audio_mode);
1358 break;
1359 } 1329 }
1360 1330
1361 case VIDIOC_G_TUNER: { 1331 v4l2_dbg(1, debug, sd, "change audio mode to %s\n",
1362 struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; 1332 mes[audio_mode]);
1363 int dual_f, stereo_f; 1333 decoder->tuner_audio_mode = audio_mode;
1334 /* The registers are not changed here. */
1335 /* See DECODER_ENABLE_OUTPUT section. */
1336 set_audio_mode(sd, decoder->tuner_audio_mode);
1337 return 0;
1338}
1364 1339
1365 if (decoder->radio) 1340static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1366 break; 1341{
1367 get_inf_dev_status(client, &dual_f, &stereo_f); 1342 struct saa717x_state *decoder = to_state(sd);
1343 int dual_f, stereo_f;
1368 1344
1369 v4l_dbg(1, debug, client, "DETECT==st:%d dual:%d\n", 1345 if (decoder->radio)
1370 stereo_f, dual_f); 1346 return 0;
1347 get_inf_dev_status(sd, &dual_f, &stereo_f);
1371 1348
1372 /* mono */ 1349 v4l2_dbg(1, debug, sd, "DETECT==st:%d dual:%d\n",
1373 if ((dual_f == 0) && (stereo_f == 0)) { 1350 stereo_f, dual_f);
1374 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1375 v4l_dbg(1, debug, client, "DETECT==MONO\n");
1376 }
1377 1351
1378 /* stereo */ 1352 /* mono */
1379 if (stereo_f == 1) { 1353 if ((dual_f == 0) && (stereo_f == 0)) {
1380 if (vt->audmode == V4L2_TUNER_MODE_STEREO || 1354 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1381 vt->audmode == V4L2_TUNER_MODE_LANG1) { 1355 v4l2_dbg(1, debug, sd, "DETECT==MONO\n");
1382 vt->rxsubchans = V4L2_TUNER_SUB_STEREO; 1356 }
1383 v4l_dbg(1, debug, client, "DETECT==ST(ST)\n");
1384 } else {
1385 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1386 v4l_dbg(1, debug, client, "DETECT==ST(MONO)\n");
1387 }
1388 }
1389 1357
1390 /* dual */ 1358 /* stereo */
1391 if (dual_f == 1) { 1359 if (stereo_f == 1) {
1392 if (vt->audmode == V4L2_TUNER_MODE_LANG2) { 1360 if (vt->audmode == V4L2_TUNER_MODE_STEREO ||
1393 vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO; 1361 vt->audmode == V4L2_TUNER_MODE_LANG1) {
1394 v4l_dbg(1, debug, client, "DETECT==DUAL1\n"); 1362 vt->rxsubchans = V4L2_TUNER_SUB_STEREO;
1395 } else { 1363 v4l2_dbg(1, debug, sd, "DETECT==ST(ST)\n");
1396 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO; 1364 } else {
1397 v4l_dbg(1, debug, client, "DETECT==DUAL2\n"); 1365 vt->rxsubchans = V4L2_TUNER_SUB_MONO;
1398 } 1366 v4l2_dbg(1, debug, sd, "DETECT==ST(MONO)\n");
1399 } 1367 }
1400 break;
1401 } 1368 }
1402 1369
1403 case VIDIOC_LOG_STATUS: 1370 /* dual */
1404 /* not yet implemented */ 1371 if (dual_f == 1) {
1405 break; 1372 if (vt->audmode == V4L2_TUNER_MODE_LANG2) {
1406 1373 vt->rxsubchans = V4L2_TUNER_SUB_LANG2 | V4L2_TUNER_SUB_MONO;
1407 default: 1374 v4l2_dbg(1, debug, sd, "DETECT==DUAL1\n");
1408 return -EINVAL; 1375 } else {
1376 vt->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_MONO;
1377 v4l2_dbg(1, debug, sd, "DETECT==DUAL2\n");
1378 }
1409 } 1379 }
1410
1411 return 0; 1380 return 0;
1412} 1381}
1413 1382
1383static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
1384{
1385 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1386}
1387
1388/* ----------------------------------------------------------------------- */
1389
1390static const struct v4l2_subdev_core_ops saa717x_core_ops = {
1391#ifdef CONFIG_VIDEO_ADV_DEBUG
1392 .g_register = saa717x_g_register,
1393 .s_register = saa717x_s_register,
1394#endif
1395 .queryctrl = saa717x_queryctrl,
1396 .g_ctrl = saa717x_g_ctrl,
1397 .s_ctrl = saa717x_s_ctrl,
1398};
1399
1400static const struct v4l2_subdev_tuner_ops saa717x_tuner_ops = {
1401 .g_tuner = saa717x_g_tuner,
1402 .s_tuner = saa717x_s_tuner,
1403 .s_std = saa717x_s_std,
1404 .s_radio = saa717x_s_radio,
1405};
1406
1407static const struct v4l2_subdev_video_ops saa717x_video_ops = {
1408 .s_routing = saa717x_s_video_routing,
1409 .s_fmt = saa717x_s_fmt,
1410 .s_stream = saa717x_s_stream,
1411};
1412
1413static const struct v4l2_subdev_audio_ops saa717x_audio_ops = {
1414 .s_routing = saa717x_s_audio_routing,
1415};
1416
1417static const struct v4l2_subdev_ops saa717x_ops = {
1418 .core = &saa717x_core_ops,
1419 .tuner = &saa717x_tuner_ops,
1420 .audio = &saa717x_audio_ops,
1421 .video = &saa717x_video_ops,
1422};
1423
1414/* ----------------------------------------------------------------------- */ 1424/* ----------------------------------------------------------------------- */
1415 1425
1416 1426
@@ -1421,6 +1431,7 @@ static int saa717x_probe(struct i2c_client *client,
1421 const struct i2c_device_id *did) 1431 const struct i2c_device_id *did)
1422{ 1432{
1423 struct saa717x_state *decoder; 1433 struct saa717x_state *decoder;
1434 struct v4l2_subdev *sd;
1424 u8 id = 0; 1435 u8 id = 0;
1425 char *p = ""; 1436 char *p = "";
1426 1437
@@ -1428,13 +1439,21 @@ static int saa717x_probe(struct i2c_client *client,
1428 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1439 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1429 return -EIO; 1440 return -EIO;
1430 1441
1431 if (saa717x_write(client, 0x5a4, 0xfe) && 1442 decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
1432 saa717x_write(client, 0x5a5, 0x0f) && 1443 if (decoder == NULL)
1433 saa717x_write(client, 0x5a6, 0x00) && 1444 return -ENOMEM;
1434 saa717x_write(client, 0x5a7, 0x01)) 1445
1435 id = saa717x_read(client, 0x5a0); 1446 sd = &decoder->sd;
1447 v4l2_i2c_subdev_init(sd, client, &saa717x_ops);
1448
1449 if (saa717x_write(sd, 0x5a4, 0xfe) &&
1450 saa717x_write(sd, 0x5a5, 0x0f) &&
1451 saa717x_write(sd, 0x5a6, 0x00) &&
1452 saa717x_write(sd, 0x5a7, 0x01))
1453 id = saa717x_read(sd, 0x5a0);
1436 if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) { 1454 if (id != 0xc2 && id != 0x32 && id != 0xf2 && id != 0x6c) {
1437 v4l_dbg(1, debug, client, "saa717x not found (id=%02x)\n", id); 1455 v4l2_dbg(1, debug, sd, "saa717x not found (id=%02x)\n", id);
1456 kfree(decoder);
1438 return -ENODEV; 1457 return -ENODEV;
1439 } 1458 }
1440 if (id == 0xc2) 1459 if (id == 0xc2)
@@ -1445,14 +1464,8 @@ static int saa717x_probe(struct i2c_client *client,
1445 p = "saa7174HL"; 1464 p = "saa7174HL";
1446 else 1465 else
1447 p = "saa7171"; 1466 p = "saa7171";
1448 v4l_info(client, "%s found @ 0x%x (%s)\n", p, 1467 v4l2_info(sd, "%s found @ 0x%x (%s)\n", p,
1449 client->addr << 1, client->adapter->name); 1468 client->addr << 1, client->adapter->name);
1450
1451 decoder = kzalloc(sizeof(struct saa717x_state), GFP_KERNEL);
1452 i2c_set_clientdata(client, decoder);
1453
1454 if (decoder == NULL)
1455 return -ENOMEM;
1456 decoder->std = V4L2_STD_NTSC; 1469 decoder->std = V4L2_STD_NTSC;
1457 decoder->input = -1; 1470 decoder->input = -1;
1458 decoder->enable = 1; 1471 decoder->enable = 1;
@@ -1481,15 +1494,15 @@ static int saa717x_probe(struct i2c_client *client,
1481 decoder->audio_main_volume = 1494 decoder->audio_main_volume =
1482 (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40)); 1495 (decoder->audio_main_vol_r + 41) * 65535 / (24 - (-40));
1483 1496
1484 v4l_dbg(1, debug, client, "writing init values\n"); 1497 v4l2_dbg(1, debug, sd, "writing init values\n");
1485 1498
1486 /* FIXME!! */ 1499 /* FIXME!! */
1487 saa717x_write_regs(client, reg_init_initialize); 1500 saa717x_write_regs(sd, reg_init_initialize);
1488 set_video_output_level_regs(client, decoder); 1501 set_video_output_level_regs(sd, decoder);
1489 /* set bass,treble to 0db 20041101 K.Ohta */ 1502 /* set bass,treble to 0db 20041101 K.Ohta */
1490 decoder->audio_main_bass = 0; 1503 decoder->audio_main_bass = 0;
1491 decoder->audio_main_treble = 0; 1504 decoder->audio_main_treble = 0;
1492 set_audio_regs(client, decoder); 1505 set_audio_regs(sd, decoder);
1493 1506
1494 set_current_state(TASK_INTERRUPTIBLE); 1507 set_current_state(TASK_INTERRUPTIBLE);
1495 schedule_timeout(2*HZ); 1508 schedule_timeout(2*HZ);
@@ -1498,7 +1511,10 @@ static int saa717x_probe(struct i2c_client *client,
1498 1511
1499static int saa717x_remove(struct i2c_client *client) 1512static int saa717x_remove(struct i2c_client *client)
1500{ 1513{
1501 kfree(i2c_get_clientdata(client)); 1514 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1515
1516 v4l2_device_unregister_subdev(sd);
1517 kfree(to_state(sd));
1502 return 0; 1518 return 0;
1503} 1519}
1504 1520