aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7115.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-11-29 10:55:19 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:40 -0500
commit9415f4b2166e6d9b3095fef47f4aa7dac76ac037 (patch)
tree240fa0091c137bff3c42fb5a85f5e69be58223ca /drivers/media/video/saa7115.c
parent76efd62f1546c6fab2116d3ba832403387bd3d4a (diff)
V4L/DVB (9826): saa7115: 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/saa7115.c')
-rw-r--r--drivers/media/video/saa7115.c763
1 files changed, 399 insertions, 364 deletions
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index c8e9cb3db30..22708ecdf1b 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -44,7 +44,7 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#include <linux/i2c.h> 45#include <linux/i2c.h>
46#include <linux/videodev2.h> 46#include <linux/videodev2.h>
47#include <media/v4l2-common.h> 47#include <media/v4l2-device.h>
48#include <media/v4l2-chip-ident.h> 48#include <media/v4l2-chip-ident.h>
49#include <media/v4l2-i2c-drv-legacy.h> 49#include <media/v4l2-i2c-drv-legacy.h>
50#include <media/saa7115.h> 50#include <media/saa7115.h>
@@ -70,6 +70,7 @@ static unsigned short normal_i2c[] = {
70I2C_CLIENT_INSMOD; 70I2C_CLIENT_INSMOD;
71 71
72struct saa711x_state { 72struct saa711x_state {
73 struct v4l2_subdev sd;
73 v4l2_std_id std; 74 v4l2_std_id std;
74 int input; 75 int input;
75 int output; 76 int output;
@@ -89,10 +90,17 @@ struct saa711x_state {
89 u8 apll; 90 u8 apll;
90}; 91};
91 92
93static inline struct saa711x_state *to_state(struct v4l2_subdev *sd)
94{
95 return container_of(sd, struct saa711x_state, sd);
96}
97
92/* ----------------------------------------------------------------------- */ 98/* ----------------------------------------------------------------------- */
93 99
94static inline int saa711x_write(struct i2c_client *client, u8 reg, u8 value) 100static inline int saa711x_write(struct v4l2_subdev *sd, u8 reg, u8 value)
95{ 101{
102 struct i2c_client *client = v4l2_get_subdevdata(sd);
103
96 return i2c_smbus_write_byte_data(client, reg, value); 104 return i2c_smbus_write_byte_data(client, reg, value);
97} 105}
98 106
@@ -128,9 +136,9 @@ static int saa711x_has_reg(const int id, const u8 reg)
128 return 1; 136 return 1;
129} 137}
130 138
131static int saa711x_writeregs(struct i2c_client *client, const unsigned char *regs) 139static int saa711x_writeregs(struct v4l2_subdev *sd, const unsigned char *regs)
132{ 140{
133 struct saa711x_state *state = i2c_get_clientdata(client); 141 struct saa711x_state *state = to_state(sd);
134 unsigned char reg, data; 142 unsigned char reg, data;
135 143
136 while (*regs != 0x00) { 144 while (*regs != 0x00) {
@@ -139,18 +147,20 @@ static int saa711x_writeregs(struct i2c_client *client, const unsigned char *reg
139 147
140 /* According with datasheets, reserved regs should be 148 /* According with datasheets, reserved regs should be
141 filled with 0 - seems better not to touch on they */ 149 filled with 0 - seems better not to touch on they */
142 if (saa711x_has_reg(state->ident,reg)) { 150 if (saa711x_has_reg(state->ident, reg)) {
143 if (saa711x_write(client, reg, data) < 0) 151 if (saa711x_write(sd, reg, data) < 0)
144 return -1; 152 return -1;
145 } else { 153 } else {
146 v4l_dbg(1, debug, client, "tried to access reserved reg 0x%02x\n", reg); 154 v4l2_dbg(1, debug, sd, "tried to access reserved reg 0x%02x\n", reg);
147 } 155 }
148 } 156 }
149 return 0; 157 return 0;
150} 158}
151 159
152static inline int saa711x_read(struct i2c_client *client, u8 reg) 160static inline int saa711x_read(struct v4l2_subdev *sd, u8 reg)
153{ 161{
162 struct i2c_client *client = v4l2_get_subdevdata(sd);
163
154 return i2c_smbus_read_byte_data(client, reg); 164 return i2c_smbus_read_byte_data(client, reg);
155} 165}
156 166
@@ -601,7 +611,7 @@ static int saa711x_odd_parity(u8 c)
601 return c & 1; 611 return c & 1;
602} 612}
603 613
604static int saa711x_decode_vps(u8 * dst, u8 * p) 614static int saa711x_decode_vps(u8 *dst, u8 *p)
605{ 615{
606 static const u8 biphase_tbl[] = { 616 static const u8 biphase_tbl[] = {
607 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, 617 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4,
@@ -648,7 +658,7 @@ static int saa711x_decode_vps(u8 * dst, u8 * p)
648 return err & 0xf0; 658 return err & 0xf0;
649} 659}
650 660
651static int saa711x_decode_wss(u8 * p) 661static int saa711x_decode_wss(u8 *p)
652{ 662{
653 static const int wss_bits[8] = { 663 static const int wss_bits[8] = {
654 0, 0, 0, 1, 0, 1, 1, 1 664 0, 0, 0, 1, 0, 1, 1, 1
@@ -675,9 +685,9 @@ static int saa711x_decode_wss(u8 * p)
675 return wss; 685 return wss;
676} 686}
677 687
678static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq) 688static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
679{ 689{
680 struct saa711x_state *state = i2c_get_clientdata(client); 690 struct saa711x_state *state = to_state(sd);
681 u32 acpf; 691 u32 acpf;
682 u32 acni; 692 u32 acni;
683 u32 hz; 693 u32 hz;
@@ -685,10 +695,10 @@ static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
685 u8 acc = 0; /* reg 0x3a, audio clock control */ 695 u8 acc = 0; /* reg 0x3a, audio clock control */
686 696
687 /* Checks for chips that don't have audio clock (saa7111, saa7113) */ 697 /* Checks for chips that don't have audio clock (saa7111, saa7113) */
688 if (!saa711x_has_reg(state->ident,R_30_AUD_MAST_CLK_CYCLES_PER_FIELD)) 698 if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
689 return 0; 699 return 0;
690 700
691 v4l_dbg(1, debug, client, "set audio clock freq: %d\n", freq); 701 v4l2_dbg(1, debug, sd, "set audio clock freq: %d\n", freq);
692 702
693 /* sanity check */ 703 /* sanity check */
694 if (freq < 32000 || freq > 48000) 704 if (freq < 32000 || freq > 48000)
@@ -715,66 +725,66 @@ static int saa711x_set_audio_clock_freq(struct i2c_client *client, u32 freq)
715 if (state->apll) 725 if (state->apll)
716 acc |= 0x08; 726 acc |= 0x08;
717 727
718 saa711x_write(client, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03); 728 saa711x_write(sd, R_38_CLK_RATIO_AMXCLK_TO_ASCLK, 0x03);
719 saa711x_write(client, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10); 729 saa711x_write(sd, R_39_CLK_RATIO_ASCLK_TO_ALRCLK, 0x10);
720 saa711x_write(client, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc); 730 saa711x_write(sd, R_3A_AUD_CLK_GEN_BASIC_SETUP, acc);
721 731
722 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff); 732 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD, acpf & 0xff);
723 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1, 733 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+1,
724 (acpf >> 8) & 0xff); 734 (acpf >> 8) & 0xff);
725 saa711x_write(client, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2, 735 saa711x_write(sd, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD+2,
726 (acpf >> 16) & 0x03); 736 (acpf >> 16) & 0x03);
727 737
728 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff); 738 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC, acni & 0xff);
729 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff); 739 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+1, (acni >> 8) & 0xff);
730 saa711x_write(client, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f); 740 saa711x_write(sd, R_34_AUD_MAST_CLK_NOMINAL_INC+2, (acni >> 16) & 0x3f);
731 state->audclk_freq = freq; 741 state->audclk_freq = freq;
732 return 0; 742 return 0;
733} 743}
734 744
735static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 745static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
736{ 746{
737 struct saa711x_state *state = i2c_get_clientdata(client); 747 struct saa711x_state *state = to_state(sd);
738 748
739 switch (ctrl->id) { 749 switch (ctrl->id) {
740 case V4L2_CID_BRIGHTNESS: 750 case V4L2_CID_BRIGHTNESS:
741 if (ctrl->value < 0 || ctrl->value > 255) { 751 if (ctrl->value < 0 || ctrl->value > 255) {
742 v4l_err(client, "invalid brightness setting %d\n", ctrl->value); 752 v4l2_err(sd, "invalid brightness setting %d\n", ctrl->value);
743 return -ERANGE; 753 return -ERANGE;
744 } 754 }
745 755
746 state->bright = ctrl->value; 756 state->bright = ctrl->value;
747 saa711x_write(client, R_0A_LUMA_BRIGHT_CNTL, state->bright); 757 saa711x_write(sd, R_0A_LUMA_BRIGHT_CNTL, state->bright);
748 break; 758 break;
749 759
750 case V4L2_CID_CONTRAST: 760 case V4L2_CID_CONTRAST:
751 if (ctrl->value < 0 || ctrl->value > 127) { 761 if (ctrl->value < 0 || ctrl->value > 127) {
752 v4l_err(client, "invalid contrast setting %d\n", ctrl->value); 762 v4l2_err(sd, "invalid contrast setting %d\n", ctrl->value);
753 return -ERANGE; 763 return -ERANGE;
754 } 764 }
755 765
756 state->contrast = ctrl->value; 766 state->contrast = ctrl->value;
757 saa711x_write(client, R_0B_LUMA_CONTRAST_CNTL, state->contrast); 767 saa711x_write(sd, R_0B_LUMA_CONTRAST_CNTL, state->contrast);
758 break; 768 break;
759 769
760 case V4L2_CID_SATURATION: 770 case V4L2_CID_SATURATION:
761 if (ctrl->value < 0 || ctrl->value > 127) { 771 if (ctrl->value < 0 || ctrl->value > 127) {
762 v4l_err(client, "invalid saturation setting %d\n", ctrl->value); 772 v4l2_err(sd, "invalid saturation setting %d\n", ctrl->value);
763 return -ERANGE; 773 return -ERANGE;
764 } 774 }
765 775
766 state->sat = ctrl->value; 776 state->sat = ctrl->value;
767 saa711x_write(client, R_0C_CHROMA_SAT_CNTL, state->sat); 777 saa711x_write(sd, R_0C_CHROMA_SAT_CNTL, state->sat);
768 break; 778 break;
769 779
770 case V4L2_CID_HUE: 780 case V4L2_CID_HUE:
771 if (ctrl->value < -127 || ctrl->value > 127) { 781 if (ctrl->value < -127 || ctrl->value > 127) {
772 v4l_err(client, "invalid hue setting %d\n", ctrl->value); 782 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
773 return -ERANGE; 783 return -ERANGE;
774 } 784 }
775 785
776 state->hue = ctrl->value; 786 state->hue = ctrl->value;
777 saa711x_write(client, R_0D_CHROMA_HUE_CNTL, state->hue); 787 saa711x_write(sd, R_0D_CHROMA_HUE_CNTL, state->hue);
778 break; 788 break;
779 789
780 default: 790 default:
@@ -784,9 +794,9 @@ static int saa711x_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c
784 return 0; 794 return 0;
785} 795}
786 796
787static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) 797static int saa711x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
788{ 798{
789 struct saa711x_state *state = i2c_get_clientdata(client); 799 struct saa711x_state *state = to_state(sd);
790 800
791 switch (ctrl->id) { 801 switch (ctrl->id) {
792 case V4L2_CID_BRIGHTNESS: 802 case V4L2_CID_BRIGHTNESS:
@@ -808,16 +818,16 @@ static int saa711x_get_v4lctrl(struct i2c_client *client, struct v4l2_control *c
808 return 0; 818 return 0;
809} 819}
810 820
811static int saa711x_set_size(struct i2c_client *client, int width, int height) 821static int saa711x_set_size(struct v4l2_subdev *sd, int width, int height)
812{ 822{
813 struct saa711x_state *state = i2c_get_clientdata(client); 823 struct saa711x_state *state = to_state(sd);
814 int HPSC, HFSC; 824 int HPSC, HFSC;
815 int VSCY; 825 int VSCY;
816 int res; 826 int res;
817 int is_50hz = state->std & V4L2_STD_625_50; 827 int is_50hz = state->std & V4L2_STD_625_50;
818 int Vsrc = is_50hz ? 576 : 480; 828 int Vsrc = is_50hz ? 576 : 480;
819 829
820 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height); 830 v4l2_dbg(1, debug, sd, "decoder set size to %ix%i\n", width, height);
821 831
822 /* FIXME need better bounds checking here */ 832 /* FIXME need better bounds checking here */
823 if ((width < 1) || (width > 1440)) 833 if ((width < 1) || (width > 1440))
@@ -825,7 +835,7 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
825 if ((height < 1) || (height > Vsrc)) 835 if ((height < 1) || (height > Vsrc))
826 return -EINVAL; 836 return -EINVAL;
827 837
828 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) { 838 if (!saa711x_has_reg(state->ident, R_D0_B_HORIZ_PRESCALING)) {
829 /* Decoder only supports 720 columns and 480 or 576 lines */ 839 /* Decoder only supports 720 columns and 480 or 576 lines */
830 if (width != 720) 840 if (width != 720)
831 return -EINVAL; 841 return -EINVAL;
@@ -843,22 +853,22 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
843 /* Set output width/height */ 853 /* Set output width/height */
844 /* width */ 854 /* width */
845 855
846 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 856 saa711x_write(sd, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
847 (u8) (width & 0xff)); 857 (u8) (width & 0xff));
848 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 858 saa711x_write(sd, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
849 (u8) ((width >> 8) & 0xff)); 859 (u8) ((width >> 8) & 0xff));
850 860
851 /* Vertical Scaling uses height/2 */ 861 /* Vertical Scaling uses height/2 */
852 res=height/2; 862 res = height / 2;
853 863
854 /* On 60Hz, it is using a higher Vertical Output Size */ 864 /* On 60Hz, it is using a higher Vertical Output Size */
855 if (!is_50hz) 865 if (!is_50hz)
856 res += (VRES_60HZ - 480) >> 1; 866 res += (VRES_60HZ - 480) >> 1;
857 867
858 /* height */ 868 /* height */
859 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 869 saa711x_write(sd, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
860 (u8) (res & 0xff)); 870 (u8) (res & 0xff));
861 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 871 saa711x_write(sd, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
862 (u8) ((res >> 8) & 0xff)); 872 (u8) ((res >> 8) & 0xff));
863 873
864 /* Scaling settings */ 874 /* Scaling settings */
@@ -869,54 +879,54 @@ static int saa711x_set_size(struct i2c_client *client, int width, int height)
869 HFSC = (int)((1024 * 720) / (HPSC * width)); 879 HFSC = (int)((1024 * 720) / (HPSC * width));
870 /* FIXME hardcodes to "Task B" 880 /* FIXME hardcodes to "Task B"
871 * write H prescaler integer */ 881 * write H prescaler integer */
872 saa711x_write(client, R_D0_B_HORIZ_PRESCALING, 882 saa711x_write(sd, R_D0_B_HORIZ_PRESCALING,
873 (u8) (HPSC & 0x3f)); 883 (u8) (HPSC & 0x3f));
874 884
875 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); 885 v4l2_dbg(1, debug, sd, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
876 /* write H fine-scaling (luminance) */ 886 /* write H fine-scaling (luminance) */
877 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC, 887 saa711x_write(sd, R_D8_B_HORIZ_LUMA_SCALING_INC,
878 (u8) (HFSC & 0xff)); 888 (u8) (HFSC & 0xff));
879 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 889 saa711x_write(sd, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
880 (u8) ((HFSC >> 8) & 0xff)); 890 (u8) ((HFSC >> 8) & 0xff));
881 /* write H fine-scaling (chrominance) 891 /* write H fine-scaling (chrominance)
882 * must be lum/2, so i'll just bitshift :) */ 892 * must be lum/2, so i'll just bitshift :) */
883 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING, 893 saa711x_write(sd, R_DC_B_HORIZ_CHROMA_SCALING,
884 (u8) ((HFSC >> 1) & 0xff)); 894 (u8) ((HFSC >> 1) & 0xff));
885 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB, 895 saa711x_write(sd, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
886 (u8) ((HFSC >> 9) & 0xff)); 896 (u8) ((HFSC >> 9) & 0xff));
887 897
888 VSCY = (int)((1024 * Vsrc) / height); 898 VSCY = (int)((1024 * Vsrc) / height);
889 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); 899 v4l2_dbg(1, debug, sd, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
890 900
891 /* Correct Contrast and Luminance */ 901 /* Correct Contrast and Luminance */
892 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL, 902 saa711x_write(sd, R_D5_B_LUMA_CONTRAST_CNTL,
893 (u8) (64 * 1024 / VSCY)); 903 (u8) (64 * 1024 / VSCY));
894 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL, 904 saa711x_write(sd, R_D6_B_CHROMA_SATURATION_CNTL,
895 (u8) (64 * 1024 / VSCY)); 905 (u8) (64 * 1024 / VSCY));
896 906
897 /* write V fine-scaling (luminance) */ 907 /* write V fine-scaling (luminance) */
898 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC, 908 saa711x_write(sd, R_E0_B_VERT_LUMA_SCALING_INC,
899 (u8) (VSCY & 0xff)); 909 (u8) (VSCY & 0xff));
900 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB, 910 saa711x_write(sd, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
901 (u8) ((VSCY >> 8) & 0xff)); 911 (u8) ((VSCY >> 8) & 0xff));
902 /* write V fine-scaling (chrominance) */ 912 /* write V fine-scaling (chrominance) */
903 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC, 913 saa711x_write(sd, R_E2_B_VERT_CHROMA_SCALING_INC,
904 (u8) (VSCY & 0xff)); 914 (u8) (VSCY & 0xff));
905 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 915 saa711x_write(sd, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
906 (u8) ((VSCY >> 8) & 0xff)); 916 (u8) ((VSCY >> 8) & 0xff));
907 917
908 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 918 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
909 919
910 /* Activates task "B" */ 920 /* Activates task "B" */
911 saa711x_write(client, R_80_GLOBAL_CNTL_1, 921 saa711x_write(sd, R_80_GLOBAL_CNTL_1,
912 saa711x_read(client,R_80_GLOBAL_CNTL_1) | 0x20); 922 saa711x_read(sd, R_80_GLOBAL_CNTL_1) | 0x20);
913 923
914 return 0; 924 return 0;
915} 925}
916 926
917static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) 927static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
918{ 928{
919 struct saa711x_state *state = i2c_get_clientdata(client); 929 struct saa711x_state *state = to_state(sd);
920 930
921 /* Prevent unnecessary standard changes. During a standard 931 /* Prevent unnecessary standard changes. During a standard
922 change the I-Port is temporarily disabled. Any devices 932 change the I-Port is temporarily disabled. Any devices
@@ -932,13 +942,13 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
932 942
933 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. 943 // This works for NTSC-M, SECAM-L and the 50Hz PAL variants.
934 if (std & V4L2_STD_525_60) { 944 if (std & V4L2_STD_525_60) {
935 v4l_dbg(1, debug, client, "decoder set standard 60 Hz\n"); 945 v4l2_dbg(1, debug, sd, "decoder set standard 60 Hz\n");
936 saa711x_writeregs(client, saa7115_cfg_60hz_video); 946 saa711x_writeregs(sd, saa7115_cfg_60hz_video);
937 saa711x_set_size(client, 720, 480); 947 saa711x_set_size(sd, 720, 480);
938 } else { 948 } else {
939 v4l_dbg(1, debug, client, "decoder set standard 50 Hz\n"); 949 v4l2_dbg(1, debug, sd, "decoder set standard 50 Hz\n");
940 saa711x_writeregs(client, saa7115_cfg_50hz_video); 950 saa711x_writeregs(sd, saa7115_cfg_50hz_video);
941 saa711x_set_size(client, 720, 576); 951 saa711x_set_size(sd, 720, 576);
942 } 952 }
943 953
944 /* Register 0E - Bits D6-D4 on NO-AUTO mode 954 /* Register 0E - Bits D6-D4 on NO-AUTO mode
@@ -952,7 +962,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
952 */ 962 */
953 if (state->ident == V4L2_IDENT_SAA7111 || 963 if (state->ident == V4L2_IDENT_SAA7111 ||
954 state->ident == V4L2_IDENT_SAA7113) { 964 state->ident == V4L2_IDENT_SAA7113) {
955 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f; 965 u8 reg = saa711x_read(sd, R_0E_CHROMA_CNTL_1) & 0x8f;
956 966
957 if (std == V4L2_STD_PAL_M) { 967 if (std == V4L2_STD_PAL_M) {
958 reg |= 0x30; 968 reg |= 0x30;
@@ -965,87 +975,31 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
965 } else if (std & V4L2_STD_SECAM) { 975 } else if (std & V4L2_STD_SECAM) {
966 reg |= 0x50; 976 reg |= 0x50;
967 } 977 }
968 saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); 978 saa711x_write(sd, R_0E_CHROMA_CNTL_1, reg);
969 } else { 979 } else {
970 /* restart task B if needed */ 980 /* restart task B if needed */
971 int taskb = saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10; 981 int taskb = saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10;
972 982
973 if (taskb && state->ident == V4L2_IDENT_SAA7114) { 983 if (taskb && state->ident == V4L2_IDENT_SAA7114) {
974 saa711x_writeregs(client, saa7115_cfg_vbi_on); 984 saa711x_writeregs(sd, saa7115_cfg_vbi_on);
975 } 985 }
976 986
977 /* switch audio mode too! */ 987 /* switch audio mode too! */
978 saa711x_set_audio_clock_freq(client, state->audclk_freq); 988 saa711x_s_clock_freq(sd, state->audclk_freq);
979 }
980}
981
982static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
983{
984 struct saa711x_state *state = i2c_get_clientdata(client);
985
986 return state->std;
987}
988
989static void saa711x_log_status(struct i2c_client *client)
990{
991 struct saa711x_state *state = i2c_get_clientdata(client);
992 int reg1e, reg1f;
993 int signalOk;
994 int vcr;
995
996 v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq);
997 if (state->ident != V4L2_IDENT_SAA7115) {
998 /* status for the saa7114 */
999 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1000 signalOk = (reg1f & 0xc1) == 0x81;
1001 v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad");
1002 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1003 return;
1004 }
1005
1006 /* status for the saa7115 */
1007 reg1e = saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC);
1008 reg1f = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC);
1009
1010 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1011 vcr = !(reg1f & 0x10);
1012
1013 if (state->input >= 6) {
1014 v4l_info(client, "Input: S-Video %d\n", state->input - 6);
1015 } else {
1016 v4l_info(client, "Input: Composite %d\n", state->input);
1017 } 989 }
1018 v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1019 v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1020
1021 switch (reg1e & 0x03) {
1022 case 1:
1023 v4l_info(client, "Detected format: NTSC\n");
1024 break;
1025 case 2:
1026 v4l_info(client, "Detected format: PAL\n");
1027 break;
1028 case 3:
1029 v4l_info(client, "Detected format: SECAM\n");
1030 break;
1031 default:
1032 v4l_info(client, "Detected format: BW/No color\n");
1033 break;
1034 }
1035 v4l_info(client, "Width, Height: %d, %d\n", state->width, state->height);
1036} 990}
1037 991
1038/* setup the sliced VBI lcr registers according to the sliced VBI format */ 992/* setup the sliced VBI lcr registers according to the sliced VBI format */
1039static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_format *fmt) 993static void saa711x_set_lcr(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt)
1040{ 994{
1041 struct saa711x_state *state = i2c_get_clientdata(client); 995 struct saa711x_state *state = to_state(sd);
1042 int is_50hz = (state->std & V4L2_STD_625_50); 996 int is_50hz = (state->std & V4L2_STD_625_50);
1043 u8 lcr[24]; 997 u8 lcr[24];
1044 int i, x; 998 int i, x;
1045 999
1046#if 1 1000#if 1
1047 /* saa7113/7114/7118 VBI support are experimental */ 1001 /* saa7113/7114/7118 VBI support are experimental */
1048 if (!saa711x_has_reg(state->ident,R_41_LCR_BASE)) 1002 if (!saa711x_has_reg(state->ident, R_41_LCR_BASE))
1049 return; 1003 return;
1050 1004
1051#else 1005#else
@@ -1109,16 +1063,16 @@ static void saa711x_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo
1109 1063
1110 /* write the lcr registers */ 1064 /* write the lcr registers */
1111 for (i = 2; i <= 23; i++) { 1065 for (i = 2; i <= 23; i++) {
1112 saa711x_write(client, i - 2 + R_41_LCR_BASE, lcr[i]); 1066 saa711x_write(sd, i - 2 + R_41_LCR_BASE, lcr[i]);
1113 } 1067 }
1114 1068
1115 /* enable/disable raw VBI capturing */ 1069 /* enable/disable raw VBI capturing */
1116 saa711x_writeregs(client, fmt == NULL ? 1070 saa711x_writeregs(sd, fmt == NULL ?
1117 saa7115_cfg_vbi_on : 1071 saa7115_cfg_vbi_on :
1118 saa7115_cfg_vbi_off); 1072 saa7115_cfg_vbi_off);
1119} 1073}
1120 1074
1121static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1075static int saa711x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1122{ 1076{
1123 static u16 lcr2vbi[] = { 1077 static u16 lcr2vbi[] = {
1124 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 1078 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
@@ -1134,10 +1088,10 @@ static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1134 return -EINVAL; 1088 return -EINVAL;
1135 memset(sliced, 0, sizeof(*sliced)); 1089 memset(sliced, 0, sizeof(*sliced));
1136 /* done if using raw VBI */ 1090 /* done if using raw VBI */
1137 if (saa711x_read(client, R_80_GLOBAL_CNTL_1) & 0x10) 1091 if (saa711x_read(sd, R_80_GLOBAL_CNTL_1) & 0x10)
1138 return 0; 1092 return 0;
1139 for (i = 2; i <= 23; i++) { 1093 for (i = 2; i <= 23; i++) {
1140 u8 v = saa711x_read(client, i - 2 + R_41_LCR_BASE); 1094 u8 v = saa711x_read(sd, i - 2 + R_41_LCR_BASE);
1141 1095
1142 sliced->service_lines[0][i] = lcr2vbi[v >> 4]; 1096 sliced->service_lines[0][i] = lcr2vbi[v >> 4];
1143 sliced->service_lines[1][i] = lcr2vbi[v & 0xf]; 1097 sliced->service_lines[1][i] = lcr2vbi[v & 0xf];
@@ -1147,20 +1101,20 @@ static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1147 return 0; 1101 return 0;
1148} 1102}
1149 1103
1150static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1104static int saa711x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
1151{ 1105{
1152 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1106 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1153 saa711x_set_lcr(client, &fmt->fmt.sliced); 1107 saa711x_set_lcr(sd, &fmt->fmt.sliced);
1154 return 0; 1108 return 0;
1155 } 1109 }
1156 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 1110 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1157 saa711x_set_lcr(client, NULL); 1111 saa711x_set_lcr(sd, NULL);
1158 return 0; 1112 return 0;
1159 } 1113 }
1160 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1114 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1161 return -EINVAL; 1115 return -EINVAL;
1162 1116
1163 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height); 1117 return saa711x_set_size(sd, fmt->fmt.pix.width, fmt->fmt.pix.height);
1164} 1118}
1165 1119
1166/* Decode the sliced VBI data stream as created by the saa7115. 1120/* Decode the sliced VBI data stream as created by the saa7115.
@@ -1169,13 +1123,12 @@ static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1169 The current implementation uses SAV/EAV codes and not the ancillary data 1123 The current implementation uses SAV/EAV codes and not the ancillary data
1170 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV 1124 headers. The vbi->p pointer points to the R_5E_SDID byte right after the SAV
1171 code. */ 1125 code. */
1172static void saa711x_decode_vbi_line(struct i2c_client *client, 1126static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
1173 struct v4l2_decode_vbi_line *vbi)
1174{ 1127{
1128 struct saa711x_state *state = to_state(sd);
1175 static const char vbi_no_data_pattern[] = { 1129 static const char vbi_no_data_pattern[] = {
1176 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0 1130 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0
1177 }; 1131 };
1178 struct saa711x_state *state = i2c_get_clientdata(client);
1179 u8 *p = vbi->p; 1132 u8 *p = vbi->p;
1180 u32 wss; 1133 u32 wss;
1181 int id1, id2; /* the ID1 and ID2 bytes from the internal header */ 1134 int id1, id2; /* the ID1 and ID2 bytes from the internal header */
@@ -1202,7 +1155,7 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1202 /* If the VBI slicer does not detect any signal it will fill up 1155 /* If the VBI slicer does not detect any signal it will fill up
1203 the payload buffer with 0xa0 bytes. */ 1156 the payload buffer with 0xa0 bytes. */
1204 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern))) 1157 if (!memcmp(p, vbi_no_data_pattern, sizeof(vbi_no_data_pattern)))
1205 return; 1158 return 0;
1206 1159
1207 /* decode payloads */ 1160 /* decode payloads */
1208 switch (id2) { 1161 switch (id2) {
@@ -1211,275 +1164,352 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1211 break; 1164 break;
1212 case 4: 1165 case 4:
1213 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1])) 1166 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1214 return; 1167 return 0;
1215 vbi->type = V4L2_SLICED_CAPTION_525; 1168 vbi->type = V4L2_SLICED_CAPTION_525;
1216 break; 1169 break;
1217 case 5: 1170 case 5:
1218 wss = saa711x_decode_wss(p); 1171 wss = saa711x_decode_wss(p);
1219 if (wss == -1) 1172 if (wss == -1)
1220 return; 1173 return 0;
1221 p[0] = wss & 0xff; 1174 p[0] = wss & 0xff;
1222 p[1] = wss >> 8; 1175 p[1] = wss >> 8;
1223 vbi->type = V4L2_SLICED_WSS_625; 1176 vbi->type = V4L2_SLICED_WSS_625;
1224 break; 1177 break;
1225 case 7: 1178 case 7:
1226 if (saa711x_decode_vps(p, p) != 0) 1179 if (saa711x_decode_vps(p, p) != 0)
1227 return; 1180 return 0;
1228 vbi->type = V4L2_SLICED_VPS; 1181 vbi->type = V4L2_SLICED_VPS;
1229 break; 1182 break;
1230 default: 1183 default:
1231 return; 1184 break;
1232 } 1185 }
1186 return 0;
1233} 1187}
1234 1188
1235/* ============ SAA7115 AUDIO settings (end) ============= */ 1189/* ============ SAA7115 AUDIO settings (end) ============= */
1236 1190
1237static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) 1191static int saa711x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1238{ 1192{
1239 struct saa711x_state *state = i2c_get_clientdata(client); 1193 struct saa711x_state *state = to_state(sd);
1194 int status;
1240 1195
1241 /* ioctls to allow direct access to the saa7115 registers for testing */ 1196 if (state->radio)
1242 switch (cmd) { 1197 return 0;
1243 case VIDIOC_S_FMT: 1198 status = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1244 return saa711x_set_v4lfmt(client, (struct v4l2_format *)arg);
1245 1199
1246 case VIDIOC_G_FMT: 1200 v4l2_dbg(1, debug, sd, "status: 0x%02x\n", status);
1247 return saa711x_get_v4lfmt(client, (struct v4l2_format *)arg); 1201 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0;
1202 return 0;
1203}
1248 1204
1249 case VIDIOC_INT_AUDIO_CLOCK_FREQ: 1205static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1250 return saa711x_set_audio_clock_freq(client, *(u32 *)arg); 1206{
1207 switch (qc->id) {
1208 case V4L2_CID_BRIGHTNESS:
1209 case V4L2_CID_CONTRAST:
1210 case V4L2_CID_SATURATION:
1211 case V4L2_CID_HUE:
1212 return v4l2_ctrl_query_fill_std(qc);
1213 default:
1214 return -EINVAL;
1215 }
1216}
1251 1217
1252 case VIDIOC_G_TUNER: 1218static int saa711x_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1253 { 1219{
1254 struct v4l2_tuner *vt = arg; 1220 struct saa711x_state *state = to_state(sd);
1255 int status;
1256 1221
1257 if (state->radio) 1222 state->radio = 0;
1258 break; 1223 saa711x_set_v4lstd(sd, std);
1259 status = saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC); 1224 return 0;
1225}
1260 1226
1261 v4l_dbg(1, debug, client, "status: 0x%02x\n", status); 1227static int saa711x_s_radio(struct v4l2_subdev *sd)
1262 vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; 1228{
1263 break; 1229 struct saa711x_state *state = to_state(sd);
1264 }
1265 1230
1266 case VIDIOC_LOG_STATUS: 1231 state->radio = 1;
1267 saa711x_log_status(client); 1232 return 0;
1268 break; 1233}
1269 1234
1270 case VIDIOC_G_CTRL: 1235static int saa711x_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
1271 return saa711x_get_v4lctrl(client, (struct v4l2_control *)arg); 1236{
1237 struct saa711x_state *state = to_state(sd);
1238 u32 input = route->input;
1239 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
1240
1241 v4l2_dbg(1, debug, sd, "decoder set input %d output %d\n", route->input, route->output);
1242 /* saa7111/3 does not have these inputs */
1243 if ((state->ident == V4L2_IDENT_SAA7113 ||
1244 state->ident == V4L2_IDENT_SAA7111) &&
1245 (route->input == SAA7115_COMPOSITE4 ||
1246 route->input == SAA7115_COMPOSITE5)) {
1247 return -EINVAL;
1248 }
1249 if (route->input > SAA7115_SVIDEO3)
1250 return -EINVAL;
1251 if (route->output > SAA7115_IPORT_ON)
1252 return -EINVAL;
1253 if (state->input == route->input && state->output == route->output)
1254 return 0;
1255 v4l2_dbg(1, debug, sd, "now setting %s input %s output\n",
1256 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite",
1257 (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1258 state->input = route->input;
1259
1260 /* saa7111 has slightly different input numbering */
1261 if (state->ident == V4L2_IDENT_SAA7111) {
1262 if (input >= SAA7115_COMPOSITE4)
1263 input -= 2;
1264 /* saa7111 specific */
1265 saa711x_write(sd, R_10_CHROMA_CNTL_2,
1266 (saa711x_read(sd, R_10_CHROMA_CNTL_2) & 0x3f) |
1267 ((route->output & 0xc0) ^ 0x40));
1268 saa711x_write(sd, R_13_RT_X_PORT_OUT_CNTL,
1269 (saa711x_read(sd, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1270 ((route->output & 2) ? 0x0a : 0));
1271 }
1272 1272
1273 case VIDIOC_S_CTRL: 1273 /* select mode */
1274 return saa711x_set_v4lctrl(client, (struct v4l2_control *)arg); 1274 saa711x_write(sd, R_02_INPUT_CNTL_1,
1275 (saa711x_read(sd, R_02_INPUT_CNTL_1) & mask) |
1276 input);
1275 1277
1276 case VIDIOC_QUERYCTRL: 1278 /* bypass chrominance trap for S-Video modes */
1277 { 1279 saa711x_write(sd, R_09_LUMA_CNTL,
1278 struct v4l2_queryctrl *qc = arg; 1280 (saa711x_read(sd, R_09_LUMA_CNTL) & 0x7f) |
1281 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0));
1279 1282
1280 switch (qc->id) { 1283 state->output = route->output;
1281 case V4L2_CID_BRIGHTNESS: 1284 if (state->ident == V4L2_IDENT_SAA7114 ||
1282 case V4L2_CID_CONTRAST: 1285 state->ident == V4L2_IDENT_SAA7115) {
1283 case V4L2_CID_SATURATION: 1286 saa711x_write(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK,
1284 case V4L2_CID_HUE: 1287 (saa711x_read(sd, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) |
1285 return v4l2_ctrl_query_fill_std(qc); 1288 (state->output & 0x01));
1286 default:
1287 return -EINVAL;
1288 }
1289 } 1289 }
1290 return 0;
1291}
1290 1292
1291 case VIDIOC_G_STD: 1293static int saa711x_s_gpio(struct v4l2_subdev *sd, u32 val)
1292 *(v4l2_std_id *)arg = saa711x_get_v4lstd(client); 1294{
1293 break; 1295 struct saa711x_state *state = to_state(sd);
1294 1296
1295 case VIDIOC_S_STD: 1297 if (state->ident != V4L2_IDENT_SAA7111)
1296 state->radio = 0; 1298 return -EINVAL;
1297 saa711x_set_v4lstd(client, *(v4l2_std_id *)arg); 1299 saa711x_write(sd, 0x11, (saa711x_read(sd, 0x11) & 0x7f) |
1298 break; 1300 (val ? 0x80 : 0));
1301 return 0;
1302}
1299 1303
1300 case AUDC_SET_RADIO: 1304static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
1301 state->radio = 1; 1305{
1302 break; 1306 struct saa711x_state *state = to_state(sd);
1303 1307
1304 case VIDIOC_INT_G_VIDEO_ROUTING: 1308 v4l2_dbg(1, debug, sd, "%s output\n",
1305 { 1309 enable ? "enable" : "disable");
1306 struct v4l2_routing *route = arg;
1307 1310
1308 route->input = state->input; 1311 if (state->enable != enable) {
1309 route->output = state->output; 1312 state->enable = enable;
1310 break; 1313 saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1314 state->enable);
1311 } 1315 }
1316 return 0;
1317}
1312 1318
1313 case VIDIOC_INT_S_VIDEO_ROUTING: 1319static int saa711x_s_crystal_freq(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq)
1314 { 1320{
1315 struct v4l2_routing *route = arg; 1321 struct saa711x_state *state = to_state(sd);
1316 u32 input = route->input;
1317 u8 mask = (state->ident == V4L2_IDENT_SAA7111) ? 0xf8 : 0xf0;
1318
1319 v4l_dbg(1, debug, client, "decoder set input %d output %d\n", route->input, route->output);
1320 /* saa7111/3 does not have these inputs */
1321 if ((state->ident == V4L2_IDENT_SAA7113 ||
1322 state->ident == V4L2_IDENT_SAA7111) &&
1323 (route->input == SAA7115_COMPOSITE4 ||
1324 route->input == SAA7115_COMPOSITE5)) {
1325 return -EINVAL;
1326 }
1327 if (route->input > SAA7115_SVIDEO3)
1328 return -EINVAL;
1329 if (route->output > SAA7115_IPORT_ON)
1330 return -EINVAL;
1331 if (state->input == route->input && state->output == route->output)
1332 break;
1333 v4l_dbg(1, debug, client, "now setting %s input %s output\n",
1334 (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite", (route->output == SAA7115_IPORT_ON) ? "iport on" : "iport off");
1335 state->input = route->input;
1336
1337 /* saa7111 has slightly different input numbering */
1338 if (state->ident == V4L2_IDENT_SAA7111) {
1339 if (input >= SAA7115_COMPOSITE4)
1340 input -= 2;
1341 /* saa7111 specific */
1342 saa711x_write(client, R_10_CHROMA_CNTL_2,
1343 (saa711x_read(client, R_10_CHROMA_CNTL_2) & 0x3f) |
1344 ((route->output & 0xc0) ^ 0x40));
1345 saa711x_write(client, R_13_RT_X_PORT_OUT_CNTL,
1346 (saa711x_read(client, R_13_RT_X_PORT_OUT_CNTL) & 0xf0) |
1347 ((route->output & 2) ? 0x0a : 0));
1348 }
1349 1322
1350 /* select mode */ 1323 if (freq->freq != SAA7115_FREQ_32_11_MHZ &&
1351 saa711x_write(client, R_02_INPUT_CNTL_1, 1324 freq->freq != SAA7115_FREQ_24_576_MHZ)
1352 (saa711x_read(client, R_02_INPUT_CNTL_1) & mask) | 1325 return -EINVAL;
1353 input); 1326 state->crystal_freq = freq->freq;
1327 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1328 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1329 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1330 saa711x_s_clock_freq(sd, state->audclk_freq);
1331 return 0;
1332}
1354 1333
1355 /* bypass chrominance trap for S-Video modes */ 1334static int saa711x_reset(struct v4l2_subdev *sd, u32 val)
1356 saa711x_write(client, R_09_LUMA_CNTL, 1335{
1357 (saa711x_read(client, R_09_LUMA_CNTL) & 0x7f) | 1336 v4l2_dbg(1, debug, sd, "decoder RESET\n");
1358 (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); 1337 saa711x_writeregs(sd, saa7115_cfg_reset_scaler);
1338 return 0;
1339}
1359 1340
1360 state->output = route->output; 1341static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *data)
1361 if (state->ident == V4L2_IDENT_SAA7114 || 1342{
1362 state->ident == V4L2_IDENT_SAA7115) { 1343 /* Note: the internal field ID is inverted for NTSC,
1363 saa711x_write(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK, 1344 so data->field 0 maps to the saa7115 even field,
1364 (saa711x_read(client, R_83_X_PORT_I_O_ENA_AND_OUT_CLK) & 0xfe) | 1345 whereas for PAL it maps to the saa7115 odd field. */
1365 (state->output & 0x01)); 1346 switch (data->id) {
1347 case V4L2_SLICED_WSS_625:
1348 if (saa711x_read(sd, 0x6b) & 0xc0)
1349 return -EIO;
1350 data->data[0] = saa711x_read(sd, 0x6c);
1351 data->data[1] = saa711x_read(sd, 0x6d);
1352 return 0;
1353 case V4L2_SLICED_CAPTION_525:
1354 if (data->field == 0) {
1355 /* CC */
1356 if (saa711x_read(sd, 0x66) & 0x30)
1357 return -EIO;
1358 data->data[0] = saa711x_read(sd, 0x69);
1359 data->data[1] = saa711x_read(sd, 0x6a);
1360 return 0;
1366 } 1361 }
1367 break; 1362 /* XDS */
1363 if (saa711x_read(sd, 0x66) & 0xc0)
1364 return -EIO;
1365 data->data[0] = saa711x_read(sd, 0x67);
1366 data->data[1] = saa711x_read(sd, 0x68);
1367 return 0;
1368 default:
1369 return -EINVAL;
1368 } 1370 }
1371}
1369 1372
1370 case VIDIOC_STREAMON: 1373#ifdef CONFIG_VIDEO_ADV_DEBUG
1371 case VIDIOC_STREAMOFF: 1374static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1372 v4l_dbg(1, debug, client, "%s output\n", 1375{
1373 (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); 1376 struct i2c_client *client = v4l2_get_subdevdata(sd);
1374
1375 if (state->enable != (cmd == VIDIOC_STREAMON)) {
1376 state->enable = (cmd == VIDIOC_STREAMON);
1377 saa711x_write(client,
1378 R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
1379 state->enable);
1380 }
1381 break;
1382 1377
1383 case VIDIOC_INT_S_CRYSTAL_FREQ: 1378 if (!v4l2_chip_match_i2c_client(client,
1384 { 1379 reg->match_type, reg->match_chip))
1385 struct v4l2_crystal_freq *freq = arg; 1380 return -EINVAL;
1381 if (!capable(CAP_SYS_ADMIN))
1382 return -EPERM;
1383 reg->val = saa711x_read(sd, reg->reg & 0xff);
1384 return 0;
1385}
1386 1386
1387 if (freq->freq != SAA7115_FREQ_32_11_MHZ && 1387static int saa711x_s_register(struct v4l2_subdev *sd, struct v4l2_register *reg)
1388 freq->freq != SAA7115_FREQ_24_576_MHZ) 1388{
1389 return -EINVAL; 1389 struct i2c_client *client = v4l2_get_subdevdata(sd);
1390 state->crystal_freq = freq->freq;
1391 state->cgcdiv = (freq->flags & SAA7115_FREQ_FL_CGCDIV) ? 3 : 4;
1392 state->ucgc = (freq->flags & SAA7115_FREQ_FL_UCGC) ? 1 : 0;
1393 state->apll = (freq->flags & SAA7115_FREQ_FL_APLL) ? 1 : 0;
1394 saa711x_set_audio_clock_freq(client, state->audclk_freq);
1395 break;
1396 }
1397 1390
1398 case VIDIOC_INT_DECODE_VBI_LINE: 1391 if (!v4l2_chip_match_i2c_client(client,
1399 saa711x_decode_vbi_line(client, arg); 1392 reg->match_type, reg->match_chip))
1400 break; 1393 return -EINVAL;
1394 if (!capable(CAP_SYS_ADMIN))
1395 return -EPERM;
1396 saa711x_write(sd, reg->reg & 0xff, reg->val & 0xff);
1397 return 0;
1398}
1399#endif
1401 1400
1402 case VIDIOC_INT_RESET: 1401static int saa711x_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip)
1403 v4l_dbg(1, debug, client, "decoder RESET\n"); 1402{
1404 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 1403 struct saa711x_state *state = to_state(sd);
1405 break; 1404 struct i2c_client *client = v4l2_get_subdevdata(sd);
1406 1405
1407 case VIDIOC_INT_S_GPIO: 1406 return v4l2_chip_ident_i2c_client(client, chip, state->ident, 0);
1408 if (state->ident != V4L2_IDENT_SAA7111) 1407}
1409 return -EINVAL;
1410 saa711x_write(client, 0x11, (saa711x_read(client, 0x11) & 0x7f) |
1411 (*(u32 *)arg ? 0x80 : 0));
1412 break;
1413 1408
1414 case VIDIOC_INT_G_VBI_DATA: 1409static int saa711x_log_status(struct v4l2_subdev *sd)
1415 { 1410{
1416 struct v4l2_sliced_vbi_data *data = arg; 1411 struct saa711x_state *state = to_state(sd);
1412 int reg1e, reg1f;
1413 int signalOk;
1414 int vcr;
1417 1415
1418 /* Note: the internal field ID is inverted for NTSC, 1416 v4l2_info(sd, "Audio frequency: %d Hz\n", state->audclk_freq);
1419 so data->field 0 maps to the saa7115 even field, 1417 if (state->ident != V4L2_IDENT_SAA7115) {
1420 whereas for PAL it maps to the saa7115 odd field. */ 1418 /* status for the saa7114 */
1421 switch (data->id) { 1419 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1422 case V4L2_SLICED_WSS_625: 1420 signalOk = (reg1f & 0xc1) == 0x81;
1423 if (saa711x_read(client, 0x6b) & 0xc0) 1421 v4l2_info(sd, "Video signal: %s\n", signalOk ? "ok" : "bad");
1424 return -EIO; 1422 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1425 data->data[0] = saa711x_read(client, 0x6c); 1423 return 0;
1426 data->data[1] = saa711x_read(client, 0x6d);
1427 return 0;
1428 case V4L2_SLICED_CAPTION_525:
1429 if (data->field == 0) {
1430 /* CC */
1431 if (saa711x_read(client, 0x66) & 0x30)
1432 return -EIO;
1433 data->data[0] = saa711x_read(client, 0x69);
1434 data->data[1] = saa711x_read(client, 0x6a);
1435 return 0;
1436 }
1437 /* XDS */
1438 if (saa711x_read(client, 0x66) & 0xc0)
1439 return -EIO;
1440 data->data[0] = saa711x_read(client, 0x67);
1441 data->data[1] = saa711x_read(client, 0x68);
1442 return 0;
1443 default:
1444 return -EINVAL;
1445 }
1446 break;
1447 } 1424 }
1448 1425
1449#ifdef CONFIG_VIDEO_ADV_DEBUG 1426 /* status for the saa7115 */
1450 case VIDIOC_DBG_G_REGISTER: 1427 reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
1451 case VIDIOC_DBG_S_REGISTER: 1428 reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
1452 {
1453 struct v4l2_register *reg = arg;
1454 1429
1455 if (!v4l2_chip_match_i2c_client(client, reg->match_type, reg->match_chip)) 1430 signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80;
1456 return -EINVAL; 1431 vcr = !(reg1f & 0x10);
1457 if (!capable(CAP_SYS_ADMIN))
1458 return -EPERM;
1459 if (cmd == VIDIOC_DBG_G_REGISTER)
1460 reg->val = saa711x_read(client, reg->reg & 0xff);
1461 else
1462 saa711x_write(client, reg->reg & 0xff, reg->val & 0xff);
1463 break;
1464 }
1465#endif
1466 1432
1467 case VIDIOC_G_CHIP_IDENT: 1433 if (state->input >= 6)
1468 return v4l2_chip_ident_i2c_client(client, arg, state->ident, 0); 1434 v4l2_info(sd, "Input: S-Video %d\n", state->input - 6);
1435 else
1436 v4l2_info(sd, "Input: Composite %d\n", state->input);
1437 v4l2_info(sd, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad");
1438 v4l2_info(sd, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz");
1469 1439
1440 switch (reg1e & 0x03) {
1441 case 1:
1442 v4l2_info(sd, "Detected format: NTSC\n");
1443 break;
1444 case 2:
1445 v4l2_info(sd, "Detected format: PAL\n");
1446 break;
1447 case 3:
1448 v4l2_info(sd, "Detected format: SECAM\n");
1449 break;
1470 default: 1450 default:
1471 return -EINVAL; 1451 v4l2_info(sd, "Detected format: BW/No color\n");
1452 break;
1472 } 1453 }
1473 1454 v4l2_info(sd, "Width, Height: %d, %d\n", state->width, state->height);
1474 return 0; 1455 return 0;
1475} 1456}
1476 1457
1458static int saa711x_command(struct i2c_client *client, unsigned cmd, void *arg)
1459{
1460 return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
1461}
1462
1463/* ----------------------------------------------------------------------- */
1464
1465static const struct v4l2_subdev_core_ops saa711x_core_ops = {
1466 .log_status = saa711x_log_status,
1467 .g_chip_ident = saa711x_g_chip_ident,
1468 .g_ctrl = saa711x_g_ctrl,
1469 .s_ctrl = saa711x_s_ctrl,
1470 .queryctrl = saa711x_queryctrl,
1471 .reset = saa711x_reset,
1472 .s_gpio = saa711x_s_gpio,
1473#ifdef CONFIG_VIDEO_ADV_DEBUG
1474 .g_register = saa711x_g_register,
1475 .s_register = saa711x_s_register,
1476#endif
1477};
1478
1479static const struct v4l2_subdev_tuner_ops saa711x_tuner_ops = {
1480 .s_std = saa711x_s_std,
1481 .s_radio = saa711x_s_radio,
1482 .g_tuner = saa711x_g_tuner,
1483};
1484
1485static const struct v4l2_subdev_audio_ops saa711x_audio_ops = {
1486 .s_clock_freq = saa711x_s_clock_freq,
1487};
1488
1489static const struct v4l2_subdev_video_ops saa711x_video_ops = {
1490 .s_routing = saa711x_s_routing,
1491 .s_crystal_freq = saa711x_s_crystal_freq,
1492 .g_fmt = saa711x_g_fmt,
1493 .s_fmt = saa711x_s_fmt,
1494 .g_vbi_data = saa711x_g_vbi_data,
1495 .decode_vbi_line = saa711x_decode_vbi_line,
1496 .s_stream = saa711x_s_stream,
1497};
1498
1499static const struct v4l2_subdev_ops saa711x_ops = {
1500 .core = &saa711x_core_ops,
1501 .tuner = &saa711x_tuner_ops,
1502 .audio = &saa711x_audio_ops,
1503 .video = &saa711x_video_ops,
1504};
1505
1477/* ----------------------------------------------------------------------- */ 1506/* ----------------------------------------------------------------------- */
1478 1507
1479static int saa7115_probe(struct i2c_client *client, 1508static int saa711x_probe(struct i2c_client *client,
1480 const struct i2c_device_id *id) 1509 const struct i2c_device_id *id)
1481{ 1510{
1482 struct saa711x_state *state; 1511 struct saa711x_state *state;
1512 struct v4l2_subdev *sd;
1483 int i; 1513 int i;
1484 char name[17]; 1514 char name[17];
1485 char chip_id; 1515 char chip_id;
@@ -1490,8 +1520,8 @@ static int saa7115_probe(struct i2c_client *client,
1490 return -EIO; 1520 return -EIO;
1491 1521
1492 for (i = 0; i < 0x0f; i++) { 1522 for (i = 0; i < 0x0f; i++) {
1493 saa711x_write(client, 0, i); 1523 i2c_smbus_write_byte_data(client, 0, i);
1494 name[i] = (saa711x_read(client, 0) & 0x0f) + '0'; 1524 name[i] = (i2c_smbus_read_byte_data(client, 0) & 0x0f) + '0';
1495 if (name[i] > '9') 1525 if (name[i] > '9')
1496 name[i] += 'a' - '9' - 1; 1526 name[i] += 'a' - '9' - 1;
1497 } 1527 }
@@ -1518,7 +1548,8 @@ static int saa7115_probe(struct i2c_client *client,
1518 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL); 1548 state = kzalloc(sizeof(struct saa711x_state), GFP_KERNEL);
1519 if (state == NULL) 1549 if (state == NULL)
1520 return -ENOMEM; 1550 return -ENOMEM;
1521 i2c_set_clientdata(client, state); 1551 sd = &state->sd;
1552 v4l2_i2c_subdev_init(sd, client, &saa711x_ops);
1522 state->input = -1; 1553 state->input = -1;
1523 state->output = SAA7115_IPORT_ON; 1554 state->output = SAA7115_IPORT_ON;
1524 state->enable = 1; 1555 state->enable = 1;
@@ -1545,41 +1576,45 @@ static int saa7115_probe(struct i2c_client *client,
1545 break; 1576 break;
1546 default: 1577 default:
1547 state->ident = V4L2_IDENT_SAA7111; 1578 state->ident = V4L2_IDENT_SAA7111;
1548 v4l_info(client, "WARNING: Chip is not known - Falling back to saa7111\n"); 1579 v4l2_info(sd, "WARNING: Chip is not known - Falling back to saa7111\n");
1549 1580
1550 } 1581 }
1551 1582
1552 state->audclk_freq = 48000; 1583 state->audclk_freq = 48000;
1553 1584
1554 v4l_dbg(1, debug, client, "writing init values\n"); 1585 v4l2_dbg(1, debug, sd, "writing init values\n");
1555 1586
1556 /* init to 60hz/48khz */ 1587 /* init to 60hz/48khz */
1557 state->crystal_freq = SAA7115_FREQ_24_576_MHZ; 1588 state->crystal_freq = SAA7115_FREQ_24_576_MHZ;
1558 switch (state->ident) { 1589 switch (state->ident) {
1559 case V4L2_IDENT_SAA7111: 1590 case V4L2_IDENT_SAA7111:
1560 saa711x_writeregs(client, saa7111_init); 1591 saa711x_writeregs(sd, saa7111_init);
1561 break; 1592 break;
1562 case V4L2_IDENT_SAA7113: 1593 case V4L2_IDENT_SAA7113:
1563 saa711x_writeregs(client, saa7113_init); 1594 saa711x_writeregs(sd, saa7113_init);
1564 break; 1595 break;
1565 default: 1596 default:
1566 state->crystal_freq = SAA7115_FREQ_32_11_MHZ; 1597 state->crystal_freq = SAA7115_FREQ_32_11_MHZ;
1567 saa711x_writeregs(client, saa7115_init_auto_input); 1598 saa711x_writeregs(sd, saa7115_init_auto_input);
1568 } 1599 }
1569 if (state->ident != V4L2_IDENT_SAA7111) 1600 if (state->ident != V4L2_IDENT_SAA7111)
1570 saa711x_writeregs(client, saa7115_init_misc); 1601 saa711x_writeregs(sd, saa7115_init_misc);
1571 saa711x_set_v4lstd(client, V4L2_STD_NTSC); 1602 saa711x_set_v4lstd(sd, V4L2_STD_NTSC);
1572 1603
1573 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1604 v4l2_dbg(1, debug, sd, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1574 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC)); 1605 saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC),
1606 saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC));
1575 return 0; 1607 return 0;
1576} 1608}
1577 1609
1578/* ----------------------------------------------------------------------- */ 1610/* ----------------------------------------------------------------------- */
1579 1611
1580static int saa7115_remove(struct i2c_client *client) 1612static int saa711x_remove(struct i2c_client *client)
1581{ 1613{
1582 kfree(i2c_get_clientdata(client)); 1614 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1615
1616 v4l2_device_unregister_subdev(sd);
1617 kfree(to_state(sd));
1583 return 0; 1618 return 0;
1584} 1619}
1585 1620
@@ -1597,9 +1632,9 @@ MODULE_DEVICE_TABLE(i2c, saa7115_id);
1597static struct v4l2_i2c_driver_data v4l2_i2c_data = { 1632static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1598 .name = "saa7115", 1633 .name = "saa7115",
1599 .driverid = I2C_DRIVERID_SAA711X, 1634 .driverid = I2C_DRIVERID_SAA711X,
1600 .command = saa7115_command, 1635 .command = saa711x_command,
1601 .probe = saa7115_probe, 1636 .probe = saa711x_probe,
1602 .remove = saa7115_remove, 1637 .remove = saa711x_remove,
1603 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, 1638 .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
1604 .id_table = saa7115_id, 1639 .id_table = saa7115_id,
1605}; 1640};