diff options
-rw-r--r-- | drivers/staging/go7007/go7007-driver.c | 18 | ||||
-rw-r--r-- | drivers/staging/go7007/go7007-v4l2.c | 100 |
2 files changed, 47 insertions, 71 deletions
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index c5dc3b64ac03..fb1345ffb858 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c | |||
@@ -193,7 +193,8 @@ int go7007_reset_encoder(struct go7007 *go) | |||
193 | static int init_i2c_module(struct i2c_adapter *adapter, const char *type, | 193 | static int init_i2c_module(struct i2c_adapter *adapter, const char *type, |
194 | int id, int addr) | 194 | int id, int addr) |
195 | { | 195 | { |
196 | struct i2c_board_info info; | 196 | struct go7007 *go = i2c_get_adapdata(adapter); |
197 | struct v4l2_device *v4l2_dev = &go->v4l2_dev; | ||
197 | char *modname; | 198 | char *modname; |
198 | 199 | ||
199 | switch (id) { | 200 | switch (id) { |
@@ -225,14 +226,10 @@ static int init_i2c_module(struct i2c_adapter *adapter, const char *type, | |||
225 | modname = NULL; | 226 | modname = NULL; |
226 | break; | 227 | break; |
227 | } | 228 | } |
228 | if (modname != NULL) | ||
229 | request_module(modname); | ||
230 | 229 | ||
231 | memset(&info, 0, sizeof(struct i2c_board_info)); | 230 | if (v4l2_i2c_new_subdev(v4l2_dev, adapter, modname, type, addr, NULL)) |
232 | info.addr = addr; | ||
233 | strlcpy(info.type, type, I2C_NAME_SIZE); | ||
234 | if (!i2c_new_device(adapter, &info)) | ||
235 | return 0; | 231 | return 0; |
232 | |||
236 | if (modname != NULL) | 233 | if (modname != NULL) |
237 | printk(KERN_INFO | 234 | printk(KERN_INFO |
238 | "go7007: probing for module %s failed\n", modname); | 235 | "go7007: probing for module %s failed\n", modname); |
@@ -262,6 +259,11 @@ int go7007_register_encoder(struct go7007 *go) | |||
262 | if (ret < 0) | 259 | if (ret < 0) |
263 | return -1; | 260 | return -1; |
264 | 261 | ||
262 | /* v4l2 init must happen before i2c subdevs */ | ||
263 | ret = go7007_v4l2_init(go); | ||
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
265 | if (!go->i2c_adapter_online && | 267 | if (!go->i2c_adapter_online && |
266 | go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) { | 268 | go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) { |
267 | if (go7007_i2c_init(go) < 0) | 269 | if (go7007_i2c_init(go) < 0) |
@@ -282,7 +284,7 @@ int go7007_register_encoder(struct go7007 *go) | |||
282 | go->audio_enabled = 1; | 284 | go->audio_enabled = 1; |
283 | go7007_snd_init(go); | 285 | go7007_snd_init(go); |
284 | } | 286 | } |
285 | return go7007_v4l2_init(go); | 287 | return 0; |
286 | } | 288 | } |
287 | EXPORT_SYMBOL(go7007_register_encoder); | 289 | EXPORT_SYMBOL(go7007_register_encoder); |
288 | 290 | ||
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c index faa749dd0356..b18d8e2d4c5e 100644 --- a/drivers/staging/go7007/go7007-v4l2.c +++ b/drivers/staging/go7007/go7007-v4l2.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/videodev2.h> | 29 | #include <linux/videodev2.h> |
30 | #include <media/v4l2-common.h> | 30 | #include <media/v4l2-common.h> |
31 | #include <media/v4l2-ioctl.h> | 31 | #include <media/v4l2-ioctl.h> |
32 | #include <media/v4l2-subdev.h> | ||
32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
34 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
@@ -46,6 +47,9 @@ | |||
46 | #define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 | 47 | #define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 |
47 | #endif | 48 | #endif |
48 | 49 | ||
50 | #define call_all(dev, o, f, args...) \ | ||
51 | v4l2_device_call_until_err(dev, 0, o, f, ##args) | ||
52 | |||
49 | static void deactivate_buffer(struct go7007_buffer *gobuf) | 53 | static void deactivate_buffer(struct go7007_buffer *gobuf) |
50 | { | 54 | { |
51 | int i; | 55 | int i; |
@@ -247,19 +251,23 @@ static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try) | |||
247 | go->modet_map[i] = 0; | 251 | go->modet_map[i] = 0; |
248 | 252 | ||
249 | if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { | 253 | if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) { |
250 | struct video_decoder_resolution res; | 254 | struct v4l2_format res; |
255 | |||
256 | if (fmt != NULL) { | ||
257 | res = *fmt; | ||
258 | } else { | ||
259 | res.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
260 | res.fmt.pix.width = width; | ||
261 | } | ||
251 | 262 | ||
252 | res.width = width; | ||
253 | if (height > sensor_height / 2) { | 263 | if (height > sensor_height / 2) { |
254 | res.height = height / 2; | 264 | res.fmt.pix.height = height / 2; |
255 | go->encoder_v_halve = 0; | 265 | go->encoder_v_halve = 0; |
256 | } else { | 266 | } else { |
257 | res.height = height; | 267 | res.fmt.pix.height = height; |
258 | go->encoder_v_halve = 1; | 268 | go->encoder_v_halve = 1; |
259 | } | 269 | } |
260 | if (go->i2c_adapter_online) | 270 | call_all(&go->v4l2_dev, video, s_fmt, &res); |
261 | i2c_clients_command(&go->i2c_adapter, | ||
262 | DECODER_SET_RESOLUTION, &res); | ||
263 | } else { | 271 | } else { |
264 | if (width <= sensor_width / 4) { | 272 | if (width <= sensor_width / 4) { |
265 | go->encoder_h_halve = 1; | 273 | go->encoder_h_halve = 1; |
@@ -385,7 +393,7 @@ static int clip_to_modet_map(struct go7007 *go, int region, | |||
385 | } | 393 | } |
386 | #endif | 394 | #endif |
387 | 395 | ||
388 | static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl) | 396 | static int mpeg_query_ctrl(struct v4l2_queryctrl *ctrl) |
389 | { | 397 | { |
390 | static const u32 mpeg_ctrls[] = { | 398 | static const u32 mpeg_ctrls[] = { |
391 | V4L2_CID_MPEG_CLASS, | 399 | V4L2_CID_MPEG_CLASS, |
@@ -973,51 +981,35 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
973 | struct v4l2_queryctrl *query) | 981 | struct v4l2_queryctrl *query) |
974 | { | 982 | { |
975 | struct go7007 *go = ((struct go7007_file *) priv)->go; | 983 | struct go7007 *go = ((struct go7007_file *) priv)->go; |
984 | int id = query->id; | ||
976 | 985 | ||
977 | if (!go->i2c_adapter_online) | 986 | if (0 == call_all(&go->v4l2_dev, core, queryctrl, query)) |
978 | return -EIO; | 987 | return 0; |
979 | |||
980 | i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query); | ||
981 | 988 | ||
982 | return (!query->name[0]) ? mpeg_queryctrl(query) : 0; | 989 | query->id = id; |
990 | return mpeg_query_ctrl(query); | ||
983 | } | 991 | } |
984 | 992 | ||
985 | static int vidioc_g_ctrl(struct file *file, void *priv, | 993 | static int vidioc_g_ctrl(struct file *file, void *priv, |
986 | struct v4l2_control *ctrl) | 994 | struct v4l2_control *ctrl) |
987 | { | 995 | { |
988 | struct go7007 *go = ((struct go7007_file *) priv)->go; | 996 | struct go7007 *go = ((struct go7007_file *) priv)->go; |
989 | struct v4l2_queryctrl query; | ||
990 | |||
991 | if (!go->i2c_adapter_online) | ||
992 | return -EIO; | ||
993 | 997 | ||
994 | memset(&query, 0, sizeof(query)); | 998 | if (0 == call_all(&go->v4l2_dev, core, g_ctrl, ctrl)) |
995 | query.id = ctrl->id; | 999 | return 0; |
996 | i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); | ||
997 | if (query.name[0] == 0) | ||
998 | return mpeg_g_ctrl(ctrl, go); | ||
999 | i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl); | ||
1000 | 1000 | ||
1001 | return 0; | 1001 | return mpeg_g_ctrl(ctrl, go); |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | static int vidioc_s_ctrl(struct file *file, void *priv, | 1004 | static int vidioc_s_ctrl(struct file *file, void *priv, |
1005 | struct v4l2_control *ctrl) | 1005 | struct v4l2_control *ctrl) |
1006 | { | 1006 | { |
1007 | struct go7007 *go = ((struct go7007_file *) priv)->go; | 1007 | struct go7007 *go = ((struct go7007_file *) priv)->go; |
1008 | struct v4l2_queryctrl query; | ||
1009 | |||
1010 | if (!go->i2c_adapter_online) | ||
1011 | return -EIO; | ||
1012 | 1008 | ||
1013 | memset(&query, 0, sizeof(query)); | 1009 | if (0 == call_all(&go->v4l2_dev, core, s_ctrl, ctrl)) |
1014 | query.id = ctrl->id; | 1010 | return 0; |
1015 | i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); | ||
1016 | if (query.name[0] == 0) | ||
1017 | return mpeg_s_ctrl(ctrl, go); | ||
1018 | i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl); | ||
1019 | 1011 | ||
1020 | return 0; | 1012 | return mpeg_s_ctrl(ctrl, go); |
1021 | } | 1013 | } |
1022 | 1014 | ||
1023 | static int vidioc_g_parm(struct file *filp, void *priv, | 1015 | static int vidioc_g_parm(struct file *filp, void *priv, |
@@ -1135,8 +1127,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) | |||
1135 | if (go->streaming) | 1127 | if (go->streaming) |
1136 | return -EBUSY; | 1128 | return -EBUSY; |
1137 | 1129 | ||
1138 | if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && | 1130 | if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && *std != 0) |
1139 | *std != 0) | ||
1140 | return -EINVAL; | 1131 | return -EINVAL; |
1141 | 1132 | ||
1142 | if (*std == 0) | 1133 | if (*std == 0) |
@@ -1146,9 +1137,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) | |||
1146 | go->input == go->board_info->num_inputs - 1) { | 1137 | go->input == go->board_info->num_inputs - 1) { |
1147 | if (!go->i2c_adapter_online) | 1138 | if (!go->i2c_adapter_online) |
1148 | return -EIO; | 1139 | return -EIO; |
1149 | i2c_clients_command(&go->i2c_adapter, | 1140 | if (call_all(&go->v4l2_dev, core, s_std, *std) < 0) |
1150 | VIDIOC_S_STD, std); | ||
1151 | if (!*std) /* hack to indicate EINVAL from tuner */ | ||
1152 | return -EINVAL; | 1141 | return -EINVAL; |
1153 | } | 1142 | } |
1154 | 1143 | ||
@@ -1164,9 +1153,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) | |||
1164 | } else | 1153 | } else |
1165 | return -EINVAL; | 1154 | return -EINVAL; |
1166 | 1155 | ||
1167 | if (go->i2c_adapter_online) | 1156 | call_all(&go->v4l2_dev, core, s_std, *std); |
1168 | i2c_clients_command(&go->i2c_adapter, | ||
1169 | VIDIOC_S_STD, std); | ||
1170 | set_capture_size(go, NULL, 0); | 1157 | set_capture_size(go, NULL, 0); |
1171 | 1158 | ||
1172 | return 0; | 1159 | return 0; |
@@ -1180,7 +1167,7 @@ static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std) | |||
1180 | go->input == go->board_info->num_inputs - 1) { | 1167 | go->input == go->board_info->num_inputs - 1) { |
1181 | if (!go->i2c_adapter_online) | 1168 | if (!go->i2c_adapter_online) |
1182 | return -EIO; | 1169 | return -EIO; |
1183 | i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std); | 1170 | return call_all(&go->v4l2_dev, video, querystd, std); |
1184 | } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) | 1171 | } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) |
1185 | *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; | 1172 | *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; |
1186 | else | 1173 | else |
@@ -1238,14 +1225,8 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input) | |||
1238 | return -EBUSY; | 1225 | return -EBUSY; |
1239 | 1226 | ||
1240 | go->input = input; | 1227 | go->input = input; |
1241 | if (go->i2c_adapter_online) { | ||
1242 | i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT, | ||
1243 | &go->board_info->inputs[input].video_input); | ||
1244 | i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO, | ||
1245 | &go->board_info->inputs[input].audio_input); | ||
1246 | } | ||
1247 | 1228 | ||
1248 | return 0; | 1229 | return call_all(&go->v4l2_dev, video, s_routing, input, 0, 0); |
1249 | } | 1230 | } |
1250 | 1231 | ||
1251 | static int vidioc_g_tuner(struct file *file, void *priv, | 1232 | static int vidioc_g_tuner(struct file *file, void *priv, |
@@ -1260,10 +1241,7 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
1260 | if (!go->i2c_adapter_online) | 1241 | if (!go->i2c_adapter_online) |
1261 | return -EIO; | 1242 | return -EIO; |
1262 | 1243 | ||
1263 | i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t); | 1244 | return call_all(&go->v4l2_dev, tuner, g_tuner, t); |
1264 | |||
1265 | t->index = 0; | ||
1266 | return 0; | ||
1267 | } | 1245 | } |
1268 | 1246 | ||
1269 | static int vidioc_s_tuner(struct file *file, void *priv, | 1247 | static int vidioc_s_tuner(struct file *file, void *priv, |
@@ -1287,9 +1265,7 @@ static int vidioc_s_tuner(struct file *file, void *priv, | |||
1287 | break; | 1265 | break; |
1288 | } | 1266 | } |
1289 | 1267 | ||
1290 | i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t); | 1268 | return call_all(&go->v4l2_dev, tuner, s_tuner, t); |
1291 | |||
1292 | return 0; | ||
1293 | } | 1269 | } |
1294 | 1270 | ||
1295 | static int vidioc_g_frequency(struct file *file, void *priv, | 1271 | static int vidioc_g_frequency(struct file *file, void *priv, |
@@ -1303,8 +1279,8 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1303 | return -EIO; | 1279 | return -EIO; |
1304 | 1280 | ||
1305 | f->type = V4L2_TUNER_ANALOG_TV; | 1281 | f->type = V4L2_TUNER_ANALOG_TV; |
1306 | i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f); | 1282 | |
1307 | return 0; | 1283 | return call_all(&go->v4l2_dev, tuner, g_frequency, f); |
1308 | } | 1284 | } |
1309 | 1285 | ||
1310 | static int vidioc_s_frequency(struct file *file, void *priv, | 1286 | static int vidioc_s_frequency(struct file *file, void *priv, |
@@ -1317,9 +1293,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1317 | if (!go->i2c_adapter_online) | 1293 | if (!go->i2c_adapter_online) |
1318 | return -EIO; | 1294 | return -EIO; |
1319 | 1295 | ||
1320 | i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f); | 1296 | return call_all(&go->v4l2_dev, tuner, s_frequency, f); |
1321 | |||
1322 | return 0; | ||
1323 | } | 1297 | } |
1324 | 1298 | ||
1325 | static int vidioc_cropcap(struct file *file, void *priv, | 1299 | static int vidioc_cropcap(struct file *file, void *priv, |