aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7115.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2006-08-30 04:34:36 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-09-26 11:30:34 -0400
commit59ba9154952baddfaea18e9decf91c040511c0ed (patch)
tree5edceeafa6fb2e5542dea36aaf715e1d53196195 /drivers/media/video/saa7115.c
parent66ec1193ba2b4171c8f7e08245393d1b547ffd1e (diff)
V4L/DVB (4555): Cleanup: removed hardcoded tables
saa7115 module is capable of calculating the proper FIR tables. However, there were 4 hardcoded tables for the standard resolution. Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/saa7115.c')
-rw-r--r--drivers/media/video/saa7115.c236
1 files changed, 79 insertions, 157 deletions
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 740210c6fedd..08a324f9a48d 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -270,44 +270,6 @@ static const unsigned char saa7115_cfg_reset_scaler[] = {
270 270
271/* ============== SAA7715 VIDEO templates ============= */ 271/* ============== SAA7715 VIDEO templates ============= */
272 272
273/* Used on saa7114 and saa7115 */
274static const unsigned char saa7115_cfg_60hz_fullres_x[] = {
275 /* hsize = 0x2d0 = 720 */
276 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
277 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
278
279 /* Why not in 60hz-Land, too? */
280 R_D0_B_HORIZ_PRESCALING, 0x01, /* downscale = 1 */
281 /* hor lum scaling 0x0400 = 1 */
282 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00,
283 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
284
285 /* must be hor lum scaling / 2 */
286 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
287 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
288
289 0x00, 0x00
290};
291
292/* Used on saa7114 and saa7115 */
293static const unsigned char saa7115_cfg_60hz_fullres_y[] = {
294 /* output window size = 248 (but 60hz is 240?) */
295 R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0xf8,
296 R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x00,
297
298 /* Why not in 60hz-Land, too? */
299 R_D5_B_LUMA_CONTRAST_CNTL, 0x40, /* Lum contrast, nominal value = 0x40 */
300 R_D6_B_CHROMA_SATURATION_CNTL, 0x40, /* Chroma satur. nominal value = 0x80 */
301
302 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
303 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
304
305 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
306 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
307
308 0x00, 0x00
309};
310
311static const unsigned char saa7115_cfg_60hz_video[] = { 273static const unsigned char saa7115_cfg_60hz_video[] = {
312 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */ 274 R_80_GLOBAL_CNTL_1, 0x00, /* reset tasks */
313 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 275 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
@@ -386,38 +348,6 @@ static const unsigned char saa7115_cfg_60hz_video[] = {
386 0x00, 0x00 348 0x00, 0x00
387}; 349};
388 350
389static const unsigned char saa7115_cfg_50hz_fullres_x[] = {
390 /* hsize low (output), 720 same as 60hz */
391 R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 0xd0,
392 R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 0x02,
393
394 R_D0_B_HORIZ_PRESCALING, 0x01, /* down scale = 1 */
395 R_D8_B_HORIZ_LUMA_SCALING_INC, 0x00, /* hor lum scaling 0x0400 = 1 */
396 R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 0x04,
397
398 /* must be hor lum scaling / 2 */
399 R_DC_B_HORIZ_CHROMA_SCALING, 0x00,
400 R_DD_B_HORIZ_CHROMA_SCALING_MSB, 0x02,
401
402 0x00, 0x00
403};
404static const unsigned char saa7115_cfg_50hz_fullres_y[] = {
405 /* vsize low (output), 0x0120 = 288 */
406 R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 0x20,
407 R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 0x01,
408
409 R_D5_B_LUMA_CONTRAST_CNTL, 0x40, /* Lum contrast, nominal value = 0x40 */
410 R_D6_B_CHROMA_SATURATION_CNTL, 0x40, /* Chroma satur. nominal value = 0x80 */
411
412 R_E0_B_VERT_LUMA_SCALING_INC, 0x00,
413 R_E1_B_VERT_LUMA_SCALING_INC_MSB, 0x04,
414
415 R_E2_B_VERT_CHROMA_SCALING_INC, 0x00,
416 R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 0x04,
417
418 0x00, 0x00
419};
420
421static const unsigned char saa7115_cfg_50hz_video[] = { 351static const unsigned char saa7115_cfg_50hz_video[] = {
422 R_80_GLOBAL_CNTL_1, 0x00, 352 R_80_GLOBAL_CNTL_1, 0x00,
423 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */ 353 R_88_POWER_SAVE_ADC_PORT_CNTL, 0xd0, /* reset scaler */
@@ -920,6 +850,8 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
920 011 NTSC N (3.58MHz) PAL M (3.58MHz) 850 011 NTSC N (3.58MHz) PAL M (3.58MHz)
921 100 reserved NTSC-Japan (3.58MHz) 851 100 reserved NTSC-Japan (3.58MHz)
922 */ 852 */
853 state->std = std;
854
923 if (state->ident == V4L2_IDENT_SAA7111 || 855 if (state->ident == V4L2_IDENT_SAA7111 ||
924 state->ident == V4L2_IDENT_SAA7113) { 856 state->ident == V4L2_IDENT_SAA7113) {
925 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f; 857 u8 reg = saa711x_read(client, R_0E_CHROMA_CNTL_1) & 0x8f;
@@ -945,8 +877,6 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std)
945 /* switch audio mode too! */ 877 /* switch audio mode too! */
946 saa711x_set_audio_clock_freq(client, state->audclk_freq); 878 saa711x_set_audio_clock_freq(client, state->audclk_freq);
947 } 879 }
948
949 state->std = std;
950} 880}
951 881
952static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client) 882static v4l2_std_id saa711x_get_v4lstd(struct i2c_client *client)
@@ -1116,127 +1046,120 @@ static int saa711x_get_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt
1116 return 0; 1046 return 0;
1117} 1047}
1118 1048
1119static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) 1049static int saa711x_set_size(struct i2c_client *client, int width, int height)
1120{ 1050{
1121 struct saa711x_state *state = i2c_get_clientdata(client); 1051 struct saa711x_state *state = i2c_get_clientdata(client);
1122 struct v4l2_pix_format *pix;
1123 int HPSC, HFSC; 1052 int HPSC, HFSC;
1124 int VSCY; 1053 int VSCY;
1054 int res;
1125 int is_50hz = state->std & V4L2_STD_625_50; 1055 int is_50hz = state->std & V4L2_STD_625_50;
1126 int Vsrc = is_50hz ? 576 : 480; 1056 int Vsrc = is_50hz ? 576 : 480;
1127 1057
1128 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1058 v4l_dbg(1, debug, client, "decoder set size to %ix%i\n",width,height);
1129 saa711x_set_lcr(client, &fmt->fmt.sliced);
1130 return 0;
1131 }
1132 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1133 return -EINVAL;
1134
1135 pix = &(fmt->fmt.pix);
1136
1137 v4l_dbg(1, debug, client, "decoder set size\n");
1138 1059
1139 /* FIXME need better bounds checking here */ 1060 /* FIXME need better bounds checking here */
1140 if ((pix->width < 1) || (pix->width > 1440)) 1061 if ((width < 1) || (width > 1440))
1141 return -EINVAL; 1062 return -EINVAL;
1142 if ((pix->height < 1) || (pix->height > 960)) 1063 if ((height < 1) || (height > 960))
1143 return -EINVAL; 1064 return -EINVAL;
1144 1065
1145 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) { 1066 if (!saa711x_has_reg(state->ident,R_D0_B_HORIZ_PRESCALING)) {
1146 /* Decoder only supports 720 columns and 480 or 576 lines */ 1067 /* Decoder only supports 720 columns and 480 or 576 lines */
1147 if (pix->width != 720) 1068 if (width != 720)
1148 return -EINVAL; 1069 return -EINVAL;
1149 if (pix->height != Vsrc) 1070 if (height != Vsrc)
1150 return -EINVAL; 1071 return -EINVAL;
1151 } 1072 }
1073 if (!saa711x_has_reg(state->ident,R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH))
1074 return 0;
1152 1075
1153 /* probably have a valid size, let's set it */ 1076 /* probably have a valid size, let's set it */
1154 /* Set output width/height */ 1077 /* Set output width/height */
1155 /* width */ 1078 /* width */
1156 1079
1157 if (!saa711x_has_reg(state->ident,R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH)) { 1080 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH,
1158 saa711x_write(client, R_CC_B_HORIZ_OUTPUT_WINDOW_LENGTH, 1081 (u8) (width & 0xff));
1159 (u8) (pix->width & 0xff)); 1082 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB,
1160 saa711x_write(client, R_CD_B_HORIZ_OUTPUT_WINDOW_LENGTH_MSB, 1083 (u8) ((width >> 8) & 0xff));
1161 (u8) ((pix->width >> 8) & 0xff)); 1084
1085 if (height == Vsrc) {
1086 /*FIXME: This code seems weird, however, this is how it is
1087 working right now.
1088 */
1089 res=height/2;
1090 if (!is_50hz)
1091 res+=8;
1092 } else
1093 res=height;
1094
1162 /* height */ 1095 /* height */
1163 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH, 1096 saa711x_write(client, R_CE_B_VERT_OUTPUT_WINDOW_LENGTH,
1164 (u8) (pix->height & 0xff)); 1097 (u8) (res & 0xff));
1165 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB, 1098 saa711x_write(client, R_CF_B_VERT_OUTPUT_WINDOW_LENGTH_MSB,
1166 (u8) ((pix->height >> 8) & 0xff)); 1099 (u8) (res & 0xff));
1167 } 1100
1168 1101
1169 /* Scaling settings */ 1102 /* Scaling settings */
1170 /* Hprescaler is floor(inres/outres) */ 1103 /* Hprescaler is floor(inres/outres) */
1171 /* FIXME hardcoding input res */ 1104 HPSC = (int)(720 / width);
1172 if (pix->width != 720) { 1105 /* 0 is not allowed (div. by zero) */
1173 HPSC = (int)(720 / pix->width); 1106 HPSC = HPSC ? HPSC : 1;
1174 /* 0 is not allowed (div. by zero) */ 1107 HFSC = (int)((1024 * 720) / (HPSC * width));
1175 HPSC = HPSC ? HPSC : 1; 1108 /* FIXME hardcodes to "Task B"
1176 HFSC = (int)((1024 * 720) / (HPSC * pix->width)); 1109 * write H prescaler integer */
1177 1110 saa711x_write(client, R_D0_B_HORIZ_PRESCALING,
1178 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); 1111 (u8) (HPSC & 0x3f));
1179 /* FIXME hardcodes to "Task B" 1112
1180 * write H prescaler integer */ 1113 v4l_dbg(1, debug, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC);
1181 saa711x_write(client, R_D0_B_HORIZ_PRESCALING, 1114 /* write H fine-scaling (luminance) */
1182 (u8) (HPSC & 0x3f)); 1115 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC,
1183 1116 (u8) (HFSC & 0xff));
1184 /* write H fine-scaling (luminance) */ 1117 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB,
1185 saa711x_write(client, R_D8_B_HORIZ_LUMA_SCALING_INC, 1118 (u8) ((HFSC >> 8) & 0xff));
1186 (u8) (HFSC & 0xff)); 1119 /* write H fine-scaling (chrominance)
1187 saa711x_write(client, R_D9_B_HORIZ_LUMA_SCALING_INC_MSB, 1120 * must be lum/2, so i'll just bitshift :) */
1188 (u8) ((HFSC >> 8) & 0xff)); 1121 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING,
1189 /* write H fine-scaling (chrominance) 1122 (u8) ((HFSC >> 1) & 0xff));
1190 * must be lum/2, so i'll just bitshift :) */ 1123 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB,
1191 saa711x_write(client, R_DC_B_HORIZ_CHROMA_SCALING, 1124 (u8) ((HFSC >> 9) & 0xff));
1192 (u8) ((HFSC >> 1) & 0xff)); 1125
1193 saa711x_write(client, R_DD_B_HORIZ_CHROMA_SCALING_MSB, 1126 VSCY = (int)((1024 * Vsrc) / height);
1194 (u8) ((HFSC >> 9) & 0xff)); 1127 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
1195 } else { 1128
1196 if (is_50hz) { 1129 /* Correct Contrast and Luminance */
1197 v4l_dbg(1, debug, client, "Setting full 50hz width\n"); 1130 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
1198 saa711x_writeregs(client, saa7115_cfg_50hz_fullres_x);
1199 } else {
1200 v4l_dbg(1, debug, client, "Setting full 60hz width\n");
1201 saa711x_writeregs(client, saa7115_cfg_60hz_fullres_x);
1202 }
1203 }
1204
1205 if (pix->height != Vsrc) {
1206 VSCY = (int)((1024 * Vsrc) / pix->height);
1207 v4l_dbg(1, debug, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY);
1208
1209 /* Correct Contrast and Luminance */
1210 saa711x_write(client, R_D5_B_LUMA_CONTRAST_CNTL,
1211 (u8) (64 * 1024 / VSCY)); 1131 (u8) (64 * 1024 / VSCY));
1212 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL, 1132 saa711x_write(client, R_D6_B_CHROMA_SATURATION_CNTL,
1213 (u8) (64 * 1024 / VSCY)); 1133 (u8) (64 * 1024 / VSCY));
1214 1134
1215 /* write V fine-scaling (luminance) */ 1135 /* write V fine-scaling (luminance) */
1216 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC, 1136 saa711x_write(client, R_E0_B_VERT_LUMA_SCALING_INC,
1217 (u8) (VSCY & 0xff)); 1137 (u8) (VSCY & 0xff));
1218 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB, 1138 saa711x_write(client, R_E1_B_VERT_LUMA_SCALING_INC_MSB,
1219 (u8) ((VSCY >> 8) & 0xff)); 1139 (u8) ((VSCY >> 8) & 0xff));
1220 /* write V fine-scaling (chrominance) */ 1140 /* write V fine-scaling (chrominance) */
1221 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC, 1141 saa711x_write(client, R_E2_B_VERT_CHROMA_SCALING_INC,
1222 (u8) (VSCY & 0xff)); 1142 (u8) (VSCY & 0xff));
1223 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB, 1143 saa711x_write(client, R_E3_B_VERT_CHROMA_SCALING_INC_MSB,
1224 (u8) ((VSCY >> 8) & 0xff)); 1144 (u8) ((VSCY >> 8) & 0xff));
1225 } else {
1226 if (is_50hz) {
1227 v4l_dbg(1, debug, client, "Setting full 50Hz height\n");
1228 saa711x_writeregs(client, saa7115_cfg_50hz_fullres_y);
1229 } else {
1230 v4l_dbg(1, debug, client, "Setting full 60hz height\n");
1231 saa711x_writeregs(client, saa7115_cfg_60hz_fullres_y);
1232 }
1233 }
1234 1145
1235 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 1146 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
1236 1147
1237 return 0; 1148 return 0;
1238} 1149}
1239 1150
1151static int saa711x_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt)
1152{
1153 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1154 saa711x_set_lcr(client, &fmt->fmt.sliced);
1155 return 0;
1156 }
1157 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1158 return -EINVAL;
1159
1160 return saa711x_set_size(client,fmt->fmt.pix.width,fmt->fmt.pix.height);
1161}
1162
1240/* Decode the sliced VBI data stream as created by the saa7115. 1163/* Decode the sliced VBI data stream as created by the saa7115.
1241 The format is described in the saa7115 datasheet in Tables 25 and 26 1164 The format is described in the saa7115 datasheet in Tables 25 and 26
1242 and in Figure 33. 1165 and in Figure 33.
@@ -1284,7 +1207,7 @@ static void saa711x_decode_vbi_line(struct i2c_client *client,
1284 vbi->type = V4L2_SLICED_TELETEXT_B; 1207 vbi->type = V4L2_SLICED_TELETEXT_B;
1285 break; 1208 break;
1286 case 4: 1209 case 4:
1287 if (!saa711x_odd_parity(p[0]) || !saa7115_odd_parity(p[1])) 1210 if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
1288 return; 1211 return;
1289 vbi->type = V4L2_SLICED_CAPTION_525; 1212 vbi->type = V4L2_SLICED_CAPTION_525;
1290 break; 1213 break;
@@ -1570,7 +1493,6 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1570 kfree(client); 1493 kfree(client);
1571 return -ENOMEM; 1494 return -ENOMEM;
1572 } 1495 }
1573 state->std = V4L2_STD_NTSC;
1574 state->input = -1; 1496 state->input = -1;
1575 state->enable = 1; 1497 state->enable = 1;
1576 state->radio = 0; 1498 state->radio = 0;
@@ -1614,8 +1536,8 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1614 saa711x_writeregs(client, saa7115_init_auto_input); 1536 saa711x_writeregs(client, saa7115_init_auto_input);
1615 } 1537 }
1616 saa711x_writeregs(client, saa7115_init_misc); 1538 saa711x_writeregs(client, saa7115_init_misc);
1617 saa711x_writeregs(client, saa7115_cfg_60hz_fullres_x); 1539 state->std = V4L2_STD_NTSC;
1618 saa711x_writeregs(client, saa7115_cfg_60hz_fullres_y); 1540 saa711x_set_size(client, 720, 480);
1619 saa711x_writeregs(client, saa7115_cfg_60hz_video); 1541 saa711x_writeregs(client, saa7115_cfg_60hz_video);
1620 saa711x_set_audio_clock_freq(client, state->audclk_freq); 1542 saa711x_set_audio_clock_freq(client, state->audclk_freq);
1621 saa711x_writeregs(client, saa7115_cfg_reset_scaler); 1543 saa711x_writeregs(client, saa7115_cfg_reset_scaler);
@@ -1623,7 +1545,7 @@ static int saa711x_attach(struct i2c_adapter *adapter, int address, int kind)
1623 i2c_attach_client(client); 1545 i2c_attach_client(client);
1624 1546
1625 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", 1547 v4l_dbg(1, debug, client, "status: (1E) 0x%02x, (1F) 0x%02x\n",
1626 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa7115_read(client, R_1F_STATUS_BYTE_2_VD_DEC)); 1548 saa711x_read(client, R_1E_STATUS_BYTE_1_VD_DEC), saa711x_read(client, R_1F_STATUS_BYTE_2_VD_DEC));
1627 1549
1628 return 0; 1550 return 0;
1629} 1551}