diff options
Diffstat (limited to 'drivers/media/video/saa7115.c')
-rw-r--r-- | drivers/media/video/saa7115.c | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index b05015282601..dceebc0b1250 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/videodev2.h> | 41 | #include <linux/videodev2.h> |
42 | #include <media/v4l2-common.h> | 42 | #include <media/v4l2-common.h> |
43 | #include <media/saa7115.h> | ||
43 | #include <asm/div64.h> | 44 | #include <asm/div64.h> |
44 | 45 | ||
45 | MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver"); | 46 | MODULE_DESCRIPTION("Philips SAA7113/SAA7114/SAA7115 video decoder driver"); |
@@ -53,7 +54,7 @@ module_param(debug, bool, 0644); | |||
53 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 54 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
54 | 55 | ||
55 | static unsigned short normal_i2c[] = { | 56 | static unsigned short normal_i2c[] = { |
56 | 0x4a >>1, 0x48 >>1, /* SAA7113 */ | 57 | 0x4a >> 1, 0x48 >> 1, /* SAA7113 */ |
57 | 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */ | 58 | 0x42 >> 1, 0x40 >> 1, /* SAA7114 and SAA7115 */ |
58 | I2C_CLIENT_END }; | 59 | I2C_CLIENT_END }; |
59 | 60 | ||
@@ -722,16 +723,16 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
722 | 100 reserved NTSC-Japan (3.58MHz) | 723 | 100 reserved NTSC-Japan (3.58MHz) |
723 | */ | 724 | */ |
724 | if (state->ident == V4L2_IDENT_SAA7113) { | 725 | if (state->ident == V4L2_IDENT_SAA7113) { |
725 | u8 reg = saa7115_read(client, 0x0e) & 0x8f; | 726 | u8 reg = saa7115_read(client, 0x0e) & 0x8f; |
726 | 727 | ||
727 | if (std == V4L2_STD_PAL_M) { | 728 | if (std == V4L2_STD_PAL_M) { |
728 | reg|=0x30; | 729 | reg |= 0x30; |
729 | } else if (std == V4L2_STD_PAL_N) { | 730 | } else if (std == V4L2_STD_PAL_N) { |
730 | reg|=0x20; | 731 | reg |= 0x20; |
731 | } else if (std == V4L2_STD_PAL_60) { | 732 | } else if (std == V4L2_STD_PAL_60) { |
732 | reg|=0x10; | 733 | reg |= 0x10; |
733 | } else if (std == V4L2_STD_NTSC_M_JP) { | 734 | } else if (std == V4L2_STD_NTSC_M_JP) { |
734 | reg|=0x40; | 735 | reg |= 0x40; |
735 | } | 736 | } |
736 | saa7115_write(client, 0x0e, reg); | 737 | saa7115_write(client, 0x0e, reg); |
737 | } | 738 | } |
@@ -811,7 +812,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
811 | u8 lcr[24]; | 812 | u8 lcr[24]; |
812 | int i, x; | 813 | int i, x; |
813 | 814 | ||
814 | /* saa7113/71144 doesn't yet support VBI */ | 815 | /* saa7113/7114 doesn't yet support VBI */ |
815 | if (state->ident != V4L2_IDENT_SAA7115) | 816 | if (state->ident != V4L2_IDENT_SAA7115) |
816 | return; | 817 | return; |
817 | 818 | ||
@@ -851,7 +852,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
851 | case 0: | 852 | case 0: |
852 | lcr[i] |= 0xf << (4 * x); | 853 | lcr[i] |= 0xf << (4 * x); |
853 | break; | 854 | break; |
854 | case V4L2_SLICED_TELETEXT_PAL_B: | 855 | case V4L2_SLICED_TELETEXT_B: |
855 | lcr[i] |= 1 << (4 * x); | 856 | lcr[i] |= 1 << (4 * x); |
856 | break; | 857 | break; |
857 | case V4L2_SLICED_CAPTION_525: | 858 | case V4L2_SLICED_CAPTION_525: |
@@ -880,7 +881,7 @@ static void saa7115_set_lcr(struct i2c_client *client, struct v4l2_sliced_vbi_fo | |||
880 | static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) | 881 | static int saa7115_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) |
881 | { | 882 | { |
882 | static u16 lcr2vbi[] = { | 883 | static u16 lcr2vbi[] = { |
883 | 0, V4L2_SLICED_TELETEXT_PAL_B, 0, /* 1 */ | 884 | 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ |
884 | 0, V4L2_SLICED_CAPTION_525, /* 4 */ | 885 | 0, V4L2_SLICED_CAPTION_525, /* 4 */ |
885 | V4L2_SLICED_WSS_625, 0, /* 5 */ | 886 | V4L2_SLICED_WSS_625, 0, /* 5 */ |
886 | V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ | 887 | V4L2_SLICED_VPS, 0, 0, 0, 0, /* 7 */ |
@@ -1045,7 +1046,7 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, | |||
1045 | /* decode payloads */ | 1046 | /* decode payloads */ |
1046 | switch (id2) { | 1047 | switch (id2) { |
1047 | case 1: | 1048 | case 1: |
1048 | vbi->type = V4L2_SLICED_TELETEXT_PAL_B; | 1049 | vbi->type = V4L2_SLICED_TELETEXT_B; |
1049 | break; | 1050 | break; |
1050 | case 4: | 1051 | case 4: |
1051 | if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) | 1052 | if (!saa7115_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) |
@@ -1180,6 +1181,46 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar | |||
1180 | state->radio = 1; | 1181 | state->radio = 1; |
1181 | break; | 1182 | break; |
1182 | 1183 | ||
1184 | case VIDIOC_INT_G_VIDEO_ROUTING: | ||
1185 | { | ||
1186 | struct v4l2_routing *route = arg; | ||
1187 | |||
1188 | route->input = state->input; | ||
1189 | route->output = 0; | ||
1190 | break; | ||
1191 | } | ||
1192 | |||
1193 | case VIDIOC_INT_S_VIDEO_ROUTING: | ||
1194 | { | ||
1195 | struct v4l2_routing *route = arg; | ||
1196 | |||
1197 | v4l_dbg(1, debug, client, "decoder set input %d\n", route->input); | ||
1198 | /* saa7113 does not have these inputs */ | ||
1199 | if (state->ident == V4L2_IDENT_SAA7113 && | ||
1200 | (route->input == SAA7115_COMPOSITE4 || | ||
1201 | route->input == SAA7115_COMPOSITE5)) { | ||
1202 | return -EINVAL; | ||
1203 | } | ||
1204 | if (route->input > SAA7115_SVIDEO3) | ||
1205 | return -EINVAL; | ||
1206 | if (state->input == route->input) | ||
1207 | break; | ||
1208 | v4l_dbg(1, debug, client, "now setting %s input\n", | ||
1209 | (route->input >= SAA7115_SVIDEO0) ? "S-Video" : "Composite"); | ||
1210 | state->input = route->input; | ||
1211 | |||
1212 | /* select mode */ | ||
1213 | saa7115_write(client, 0x02, | ||
1214 | (saa7115_read(client, 0x02) & 0xf0) | | ||
1215 | state->input); | ||
1216 | |||
1217 | /* bypass chrominance trap for S-Video modes */ | ||
1218 | saa7115_write(client, 0x09, | ||
1219 | (saa7115_read(client, 0x09) & 0x7f) | | ||
1220 | (state->input >= SAA7115_SVIDEO0 ? 0x80 : 0x0)); | ||
1221 | break; | ||
1222 | } | ||
1223 | |||
1183 | case VIDIOC_G_INPUT: | 1224 | case VIDIOC_G_INPUT: |
1184 | *(int *)arg = state->input; | 1225 | *(int *)arg = state->input; |
1185 | break; | 1226 | break; |
@@ -1321,7 +1362,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1321 | 1362 | ||
1322 | saa7115_write(client, 0, 5); | 1363 | saa7115_write(client, 0, 5); |
1323 | chip_id = saa7115_read(client, 0) & 0x0f; | 1364 | chip_id = saa7115_read(client, 0) & 0x0f; |
1324 | if (chip_id <3 && chip_id > 5) { | 1365 | if (chip_id < 3 && chip_id > 5) { |
1325 | v4l_dbg(1, debug, client, "saa7115 not found\n"); | 1366 | v4l_dbg(1, debug, client, "saa7115 not found\n"); |
1326 | kfree(client); | 1367 | kfree(client); |
1327 | return 0; | 1368 | return 0; |
@@ -1360,7 +1401,7 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) | |||
1360 | v4l_dbg(1, debug, client, "writing init values\n"); | 1401 | v4l_dbg(1, debug, client, "writing init values\n"); |
1361 | 1402 | ||
1362 | /* init to 60hz/48khz */ | 1403 | /* init to 60hz/48khz */ |
1363 | if (state->ident==V4L2_IDENT_SAA7113) | 1404 | if (state->ident == V4L2_IDENT_SAA7113) |
1364 | saa7115_writeregs(client, saa7113_init_auto_input); | 1405 | saa7115_writeregs(client, saa7113_init_auto_input); |
1365 | else | 1406 | else |
1366 | saa7115_writeregs(client, saa7115_init_auto_input); | 1407 | saa7115_writeregs(client, saa7115_init_auto_input); |