diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-01-20 11:58:39 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-02-21 10:34:44 -0500 |
commit | ed10b06d8da204ce5f8d1b5b1a9d4df6565847c9 (patch) | |
tree | 3c4b99613fa54dce5d800d3263694ce8d470634a /drivers | |
parent | 243d8c0fd03c77051d0f6a634cbadb7bbe28a58a (diff) |
V4L/DVB (5104): Moved several stuff that were at cx88-video to cx88-blackbird.c
cx88-blackbird were using some ioctl handling that were previously on
cx88-video.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 308 |
1 files changed, 306 insertions, 2 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 9a7a2996f20f..2eb31ff0c1f4 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -53,6 +53,76 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); | |||
53 | 53 | ||
54 | /* ------------------------------------------------------------------ */ | 54 | /* ------------------------------------------------------------------ */ |
55 | 55 | ||
56 | |||
57 | struct cx88_tvnorm { | ||
58 | char *name; | ||
59 | v4l2_std_id id; | ||
60 | u32 cxiformat; | ||
61 | u32 cxoformat; | ||
62 | }; | ||
63 | |||
64 | static struct cx88_tvnorm tvnorms[] = { | ||
65 | { | ||
66 | .name = "NTSC-M", | ||
67 | .id = V4L2_STD_NTSC_M, | ||
68 | .cxiformat = VideoFormatNTSC, | ||
69 | .cxoformat = 0x181f0008, | ||
70 | },{ | ||
71 | .name = "NTSC-JP", | ||
72 | .id = V4L2_STD_NTSC_M_JP, | ||
73 | .cxiformat = VideoFormatNTSCJapan, | ||
74 | .cxoformat = 0x181f0008, | ||
75 | },{ | ||
76 | .name = "PAL-BG", | ||
77 | .id = V4L2_STD_PAL_BG, | ||
78 | .cxiformat = VideoFormatPAL, | ||
79 | .cxoformat = 0x181f0008, | ||
80 | },{ | ||
81 | .name = "PAL-DK", | ||
82 | .id = V4L2_STD_PAL_DK, | ||
83 | .cxiformat = VideoFormatPAL, | ||
84 | .cxoformat = 0x181f0008, | ||
85 | },{ | ||
86 | .name = "PAL-I", | ||
87 | .id = V4L2_STD_PAL_I, | ||
88 | .cxiformat = VideoFormatPAL, | ||
89 | .cxoformat = 0x181f0008, | ||
90 | },{ | ||
91 | .name = "PAL-M", | ||
92 | .id = V4L2_STD_PAL_M, | ||
93 | .cxiformat = VideoFormatPALM, | ||
94 | .cxoformat = 0x1c1f0008, | ||
95 | },{ | ||
96 | .name = "PAL-N", | ||
97 | .id = V4L2_STD_PAL_N, | ||
98 | .cxiformat = VideoFormatPALN, | ||
99 | .cxoformat = 0x1c1f0008, | ||
100 | },{ | ||
101 | .name = "PAL-Nc", | ||
102 | .id = V4L2_STD_PAL_Nc, | ||
103 | .cxiformat = VideoFormatPALNC, | ||
104 | .cxoformat = 0x1c1f0008, | ||
105 | },{ | ||
106 | .name = "PAL-60", | ||
107 | .id = V4L2_STD_PAL_60, | ||
108 | .cxiformat = VideoFormatPAL60, | ||
109 | .cxoformat = 0x181f0008, | ||
110 | },{ | ||
111 | .name = "SECAM-L", | ||
112 | .id = V4L2_STD_SECAM_L, | ||
113 | .cxiformat = VideoFormatSECAM, | ||
114 | .cxoformat = 0x181f0008, | ||
115 | },{ | ||
116 | .name = "SECAM-DK", | ||
117 | .id = V4L2_STD_SECAM_DK, | ||
118 | .cxiformat = VideoFormatSECAM, | ||
119 | .cxoformat = 0x181f0008, | ||
120 | } | ||
121 | }; | ||
122 | int cx88_do_ioctl( struct inode *inode, struct file *file, | ||
123 | int radio, struct cx88_core *core, unsigned int cmd, | ||
124 | void *arg, v4l2_kioctl driver_ioctl ); | ||
125 | |||
56 | #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 | 126 | #define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 |
57 | 127 | ||
58 | /* defines below are from ivtv-driver.h */ | 128 | /* defines below are from ivtv-driver.h */ |
@@ -520,7 +590,7 @@ static void blackbird_codec_settings(struct cx8802_dev *dev) | |||
520 | 590 | ||
521 | dev->params.width = dev->width; | 591 | dev->params.width = dev->width; |
522 | dev->params.height = dev->height; | 592 | dev->params.height = dev->height; |
523 | dev->params.is_50hz = (dev->core->tvnorm->id & V4L2_STD_625_50) != 0; | 593 | dev->params.is_50hz = (dev->core->tvnorm & V4L2_STD_625_50) != 0; |
524 | 594 | ||
525 | cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params); | 595 | cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params); |
526 | } | 596 | } |
@@ -918,6 +988,240 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
918 | return 0; | 988 | return 0; |
919 | } | 989 | } |
920 | 990 | ||
991 | int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | ||
992 | struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl) | ||
993 | { | ||
994 | int err; | ||
995 | |||
996 | if (debug) { | ||
997 | if (debug > 1) { | ||
998 | if (_IOC_DIR(cmd) & _IOC_WRITE) | ||
999 | v4l_printk_ioctl_arg("cx88(w)",cmd, arg); | ||
1000 | else if (!_IOC_DIR(cmd) & _IOC_READ) { | ||
1001 | v4l_print_ioctl("cx88", cmd); | ||
1002 | } | ||
1003 | } else | ||
1004 | v4l_print_ioctl(core->name,cmd); | ||
1005 | |||
1006 | } | ||
1007 | |||
1008 | switch (cmd) { | ||
1009 | /* ---------- tv norms ---------- */ | ||
1010 | case VIDIOC_ENUMSTD: | ||
1011 | { | ||
1012 | struct v4l2_standard *e = arg; | ||
1013 | unsigned int i; | ||
1014 | |||
1015 | i = e->index; | ||
1016 | if (i >= ARRAY_SIZE(tvnorms)) | ||
1017 | return -EINVAL; | ||
1018 | err = v4l2_video_std_construct(e, tvnorms[e->index].id, | ||
1019 | tvnorms[e->index].name); | ||
1020 | e->index = i; | ||
1021 | if (err < 0) | ||
1022 | return err; | ||
1023 | return 0; | ||
1024 | } | ||
1025 | case VIDIOC_G_STD: | ||
1026 | { | ||
1027 | v4l2_std_id *id = arg; | ||
1028 | |||
1029 | *id = core->tvnorm; | ||
1030 | return 0; | ||
1031 | } | ||
1032 | case VIDIOC_S_STD: | ||
1033 | { | ||
1034 | v4l2_std_id *id = arg; | ||
1035 | unsigned int i; | ||
1036 | |||
1037 | for(i = 0; i < ARRAY_SIZE(tvnorms); i++) | ||
1038 | if (*id & tvnorms[i].id) | ||
1039 | break; | ||
1040 | if (i == ARRAY_SIZE(tvnorms)) | ||
1041 | return -EINVAL; | ||
1042 | |||
1043 | mutex_lock(&core->lock); | ||
1044 | cx88_set_tvnorm(core,tvnorms[i].id); | ||
1045 | mutex_unlock(&core->lock); | ||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | /* ------ input switching ---------- */ | ||
1050 | case VIDIOC_ENUMINPUT: | ||
1051 | { | ||
1052 | static const char *iname[] = { | ||
1053 | [ CX88_VMUX_COMPOSITE1 ] = "Composite1", | ||
1054 | [ CX88_VMUX_COMPOSITE2 ] = "Composite2", | ||
1055 | [ CX88_VMUX_COMPOSITE3 ] = "Composite3", | ||
1056 | [ CX88_VMUX_COMPOSITE4 ] = "Composite4", | ||
1057 | [ CX88_VMUX_SVIDEO ] = "S-Video", | ||
1058 | [ CX88_VMUX_TELEVISION ] = "Television", | ||
1059 | [ CX88_VMUX_CABLE ] = "Cable TV", | ||
1060 | [ CX88_VMUX_DVB ] = "DVB", | ||
1061 | [ CX88_VMUX_DEBUG ] = "for debug only", | ||
1062 | }; | ||
1063 | struct v4l2_input *i = arg; | ||
1064 | unsigned int n; | ||
1065 | |||
1066 | n = i->index; | ||
1067 | if (n >= 4) | ||
1068 | return -EINVAL; | ||
1069 | if (0 == INPUT(n)->type) | ||
1070 | return -EINVAL; | ||
1071 | memset(i,0,sizeof(*i)); | ||
1072 | i->index = n; | ||
1073 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1074 | strcpy(i->name,iname[INPUT(n)->type]); | ||
1075 | if ((CX88_VMUX_TELEVISION == INPUT(n)->type) || | ||
1076 | (CX88_VMUX_CABLE == INPUT(n)->type)) | ||
1077 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1078 | for (n = 0; n < ARRAY_SIZE(tvnorms); n++) | ||
1079 | i->std |= tvnorms[n].id; | ||
1080 | return 0; | ||
1081 | } | ||
1082 | case VIDIOC_G_INPUT: | ||
1083 | { | ||
1084 | unsigned int *i = arg; | ||
1085 | |||
1086 | *i = core->input; | ||
1087 | return 0; | ||
1088 | } | ||
1089 | case VIDIOC_S_INPUT: | ||
1090 | { | ||
1091 | unsigned int *i = arg; | ||
1092 | |||
1093 | if (*i >= 4) | ||
1094 | return -EINVAL; | ||
1095 | mutex_lock(&core->lock); | ||
1096 | cx88_newstation(core); | ||
1097 | cx88_video_mux(core,*i); | ||
1098 | mutex_unlock(&core->lock); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | |||
1103 | |||
1104 | /* --- controls ---------------------------------------------- */ | ||
1105 | case VIDIOC_QUERYCTRL: | ||
1106 | { | ||
1107 | struct v4l2_queryctrl *qctrl = arg; | ||
1108 | |||
1109 | qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); | ||
1110 | if (unlikely(qctrl->id == 0)) | ||
1111 | return -EINVAL; | ||
1112 | return cx8800_ctrl_query(qctrl); | ||
1113 | } | ||
1114 | case VIDIOC_G_CTRL: | ||
1115 | return cx88_get_control(core,arg); | ||
1116 | case VIDIOC_S_CTRL: | ||
1117 | return cx88_set_control(core,arg); | ||
1118 | |||
1119 | /* --- tuner ioctls ------------------------------------------ */ | ||
1120 | case VIDIOC_G_TUNER: | ||
1121 | { | ||
1122 | struct v4l2_tuner *t = arg; | ||
1123 | u32 reg; | ||
1124 | |||
1125 | if (UNSET == core->tuner_type) | ||
1126 | return -EINVAL; | ||
1127 | if (0 != t->index) | ||
1128 | return -EINVAL; | ||
1129 | |||
1130 | memset(t,0,sizeof(*t)); | ||
1131 | strcpy(t->name, "Television"); | ||
1132 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1133 | t->capability = V4L2_TUNER_CAP_NORM; | ||
1134 | t->rangehigh = 0xffffffffUL; | ||
1135 | |||
1136 | cx88_get_stereo(core ,t); | ||
1137 | reg = cx_read(MO_DEVICE_STATUS); | ||
1138 | t->signal = (reg & (1<<5)) ? 0xffff : 0x0000; | ||
1139 | return 0; | ||
1140 | } | ||
1141 | case VIDIOC_S_TUNER: | ||
1142 | { | ||
1143 | struct v4l2_tuner *t = arg; | ||
1144 | |||
1145 | if (UNSET == core->tuner_type) | ||
1146 | return -EINVAL; | ||
1147 | if (0 != t->index) | ||
1148 | return -EINVAL; | ||
1149 | cx88_set_stereo(core, t->audmode, 1); | ||
1150 | return 0; | ||
1151 | } | ||
1152 | case VIDIOC_G_FREQUENCY: | ||
1153 | { | ||
1154 | struct v4l2_frequency *f = arg; | ||
1155 | |||
1156 | memset(f,0,sizeof(*f)); | ||
1157 | |||
1158 | if (UNSET == core->tuner_type) | ||
1159 | return -EINVAL; | ||
1160 | |||
1161 | /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ | ||
1162 | f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1163 | f->frequency = core->freq; | ||
1164 | |||
1165 | cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | case VIDIOC_S_FREQUENCY: | ||
1170 | { | ||
1171 | struct v4l2_frequency *f = arg; | ||
1172 | |||
1173 | if (UNSET == core->tuner_type) | ||
1174 | return -EINVAL; | ||
1175 | if (f->tuner != 0) | ||
1176 | return -EINVAL; | ||
1177 | if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV) | ||
1178 | return -EINVAL; | ||
1179 | if (1 == radio && f->type != V4L2_TUNER_RADIO) | ||
1180 | return -EINVAL; | ||
1181 | mutex_lock(&core->lock); | ||
1182 | core->freq = f->frequency; | ||
1183 | cx88_newstation(core); | ||
1184 | cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f); | ||
1185 | |||
1186 | /* When changing channels it is required to reset TVAUDIO */ | ||
1187 | msleep (10); | ||
1188 | cx88_set_tvaudio(core); | ||
1189 | |||
1190 | mutex_unlock(&core->lock); | ||
1191 | return 0; | ||
1192 | } | ||
1193 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1194 | /* ioctls to allow direct acces to the cx2388x registers */ | ||
1195 | case VIDIOC_INT_G_REGISTER: | ||
1196 | { | ||
1197 | struct v4l2_register *reg = arg; | ||
1198 | |||
1199 | if (reg->i2c_id != 0) | ||
1200 | return -EINVAL; | ||
1201 | /* cx2388x has a 24-bit register space */ | ||
1202 | reg->val = cx_read(reg->reg&0xffffff); | ||
1203 | return 0; | ||
1204 | } | ||
1205 | case VIDIOC_INT_S_REGISTER: | ||
1206 | { | ||
1207 | struct v4l2_register *reg = arg; | ||
1208 | |||
1209 | if (reg->i2c_id != 0) | ||
1210 | return -EINVAL; | ||
1211 | if (!capable(CAP_SYS_ADMIN)) | ||
1212 | return -EPERM; | ||
1213 | cx_write(reg->reg&0xffffff, reg->val); | ||
1214 | return 0; | ||
1215 | } | ||
1216 | #endif | ||
1217 | |||
1218 | default: | ||
1219 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | ||
1220 | driver_ioctl); | ||
1221 | } | ||
1222 | return 0; | ||
1223 | } | ||
1224 | |||
921 | int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | 1225 | int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, |
922 | unsigned int cmd, void *arg); | 1226 | unsigned int cmd, void *arg); |
923 | unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | 1227 | unsigned int (*cx88_ioctl_translator)(unsigned int cmd); |
@@ -1164,7 +1468,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv) | |||
1164 | cx2341x_fill_defaults(&dev->params); | 1468 | cx2341x_fill_defaults(&dev->params); |
1165 | dev->params.port = CX2341X_PORT_STREAMING; | 1469 | dev->params.port = CX2341X_PORT_STREAMING; |
1166 | 1470 | ||
1167 | if (core->tvnorm->id & V4L2_STD_525_60) { | 1471 | if (core->tvnorm & V4L2_STD_525_60) { |
1168 | dev->height = 480; | 1472 | dev->height = 480; |
1169 | } else { | 1473 | } else { |
1170 | dev->height = 576; | 1474 | dev->height = 576; |