diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtvfb.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtvfb.c | 91 |
1 files changed, 54 insertions, 37 deletions
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 921e281876f8..36abd2aef6f1 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #include "ivtv-driver.h" | 50 | #include "ivtv-driver.h" |
51 | #include "ivtv-cards.h" | ||
51 | #include "ivtv-i2c.h" | 52 | #include "ivtv-i2c.h" |
52 | #include "ivtv-udma.h" | 53 | #include "ivtv-udma.h" |
53 | #include "ivtv-mailbox.h" | 54 | #include "ivtv-mailbox.h" |
@@ -121,15 +122,15 @@ MODULE_LICENSE("GPL"); | |||
121 | #define IVTVFB_DEBUG(x, type, fmt, args...) \ | 122 | #define IVTVFB_DEBUG(x, type, fmt, args...) \ |
122 | do { \ | 123 | do { \ |
123 | if ((x) & ivtvfb_debug) \ | 124 | if ((x) & ivtvfb_debug) \ |
124 | printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->num , ## args); \ | 125 | printk(KERN_INFO "ivtvfb%d " type ": " fmt, itv->instance , ## args); \ |
125 | } while (0) | 126 | } while (0) |
126 | #define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args) | 127 | #define IVTVFB_DEBUG_WARN(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_WARN, "warning", fmt , ## args) |
127 | #define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args) | 128 | #define IVTVFB_DEBUG_INFO(fmt, args...) IVTVFB_DEBUG(IVTVFB_DBGFLG_INFO, "info", fmt , ## args) |
128 | 129 | ||
129 | /* Standard kernel messages */ | 130 | /* Standard kernel messages */ |
130 | #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->num , ## args) | 131 | #define IVTVFB_ERR(fmt, args...) printk(KERN_ERR "ivtvfb%d: " fmt, itv->instance , ## args) |
131 | #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->num , ## args) | 132 | #define IVTVFB_WARN(fmt, args...) printk(KERN_WARNING "ivtvfb%d: " fmt, itv->instance , ## args) |
132 | #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->num , ## args) | 133 | #define IVTVFB_INFO(fmt, args...) printk(KERN_INFO "ivtvfb%d: " fmt, itv->instance , ## args) |
133 | 134 | ||
134 | /* --------------------------------------------------------------------- */ | 135 | /* --------------------------------------------------------------------- */ |
135 | 136 | ||
@@ -895,16 +896,16 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info) | |||
895 | switch (blank_mode) { | 896 | switch (blank_mode) { |
896 | case FB_BLANK_UNBLANK: | 897 | case FB_BLANK_UNBLANK: |
897 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1); | 898 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 1); |
898 | ivtv_saa7127(itv, VIDIOC_STREAMON, NULL); | 899 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); |
899 | break; | 900 | break; |
900 | case FB_BLANK_NORMAL: | 901 | case FB_BLANK_NORMAL: |
901 | case FB_BLANK_HSYNC_SUSPEND: | 902 | case FB_BLANK_HSYNC_SUSPEND: |
902 | case FB_BLANK_VSYNC_SUSPEND: | 903 | case FB_BLANK_VSYNC_SUSPEND: |
903 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); | 904 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); |
904 | ivtv_saa7127(itv, VIDIOC_STREAMON, NULL); | 905 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 1); |
905 | break; | 906 | break; |
906 | case FB_BLANK_POWERDOWN: | 907 | case FB_BLANK_POWERDOWN: |
907 | ivtv_saa7127(itv, VIDIOC_STREAMOFF, NULL); | 908 | ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_stream, 0); |
908 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); | 909 | ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0); |
909 | break; | 910 | break; |
910 | } | 911 | } |
@@ -1188,10 +1189,45 @@ static int ivtvfb_init_card(struct ivtv *itv) | |||
1188 | 1189 | ||
1189 | } | 1190 | } |
1190 | 1191 | ||
1192 | static int __init ivtvfb_callback_init(struct device *dev, void *p) | ||
1193 | { | ||
1194 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); | ||
1195 | struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); | ||
1196 | |||
1197 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
1198 | if (ivtvfb_init_card(itv) == 0) { | ||
1199 | IVTVFB_INFO("Framebuffer registered on %s\n", | ||
1200 | itv->device.name); | ||
1201 | (*(int *)p)++; | ||
1202 | } | ||
1203 | } | ||
1204 | return 0; | ||
1205 | } | ||
1206 | |||
1207 | static int ivtvfb_callback_cleanup(struct device *dev, void *p) | ||
1208 | { | ||
1209 | struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); | ||
1210 | struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device); | ||
1211 | |||
1212 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
1213 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | ||
1214 | IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", | ||
1215 | itv->instance); | ||
1216 | return 0; | ||
1217 | } | ||
1218 | IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); | ||
1219 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); | ||
1220 | ivtvfb_release_buffers(itv); | ||
1221 | itv->osd_video_pbase = 0; | ||
1222 | } | ||
1223 | return 0; | ||
1224 | } | ||
1225 | |||
1191 | static int __init ivtvfb_init(void) | 1226 | static int __init ivtvfb_init(void) |
1192 | { | 1227 | { |
1193 | struct ivtv *itv; | 1228 | struct device_driver *drv; |
1194 | int i, registered = 0; | 1229 | int registered = 0; |
1230 | int err; | ||
1195 | 1231 | ||
1196 | if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { | 1232 | if (ivtvfb_card_id < -1 || ivtvfb_card_id >= IVTV_MAX_CARDS) { |
1197 | printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", | 1233 | printk(KERN_ERR "ivtvfb: ivtvfb_card_id parameter is out of range (valid range: -1 - %d)\n", |
@@ -1199,20 +1235,11 @@ static int __init ivtvfb_init(void) | |||
1199 | return -EINVAL; | 1235 | return -EINVAL; |
1200 | } | 1236 | } |
1201 | 1237 | ||
1202 | /* Locate & initialise all cards supporting an OSD. */ | 1238 | drv = driver_find("ivtv", &pci_bus_type); |
1203 | for (i = 0; i < ivtv_cards_active; i++) { | 1239 | err = driver_for_each_device(drv, NULL, ®istered, ivtvfb_callback_init); |
1204 | if (ivtvfb_card_id != -1 && i != ivtvfb_card_id) | 1240 | put_driver(drv); |
1205 | continue; | ||
1206 | itv = ivtv_cards[i]; | ||
1207 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { | ||
1208 | if (ivtvfb_init_card(itv) == 0) { | ||
1209 | IVTVFB_INFO("Framebuffer registered on ivtv card id %d\n", i); | ||
1210 | registered++; | ||
1211 | } | ||
1212 | } | ||
1213 | } | ||
1214 | if (!registered) { | 1241 | if (!registered) { |
1215 | printk(KERN_ERR "ivtvfb: no cards found"); | 1242 | printk(KERN_ERR "ivtvfb: no cards found\n"); |
1216 | return -ENODEV; | 1243 | return -ENODEV; |
1217 | } | 1244 | } |
1218 | return 0; | 1245 | return 0; |
@@ -1220,24 +1247,14 @@ static int __init ivtvfb_init(void) | |||
1220 | 1247 | ||
1221 | static void ivtvfb_cleanup(void) | 1248 | static void ivtvfb_cleanup(void) |
1222 | { | 1249 | { |
1223 | struct ivtv *itv; | 1250 | struct device_driver *drv; |
1224 | int i; | 1251 | int err; |
1225 | 1252 | ||
1226 | printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n"); | 1253 | printk(KERN_INFO "ivtvfb: Unloading framebuffer module\n"); |
1227 | 1254 | ||
1228 | for (i = 0; i < ivtv_cards_active; i++) { | 1255 | drv = driver_find("ivtv", &pci_bus_type); |
1229 | itv = ivtv_cards[i]; | 1256 | err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); |
1230 | if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) { | 1257 | put_driver(drv); |
1231 | if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { | ||
1232 | IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i); | ||
1233 | return; | ||
1234 | } | ||
1235 | IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i); | ||
1236 | ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info); | ||
1237 | ivtvfb_release_buffers(itv); | ||
1238 | itv->osd_video_pbase = 0; | ||
1239 | } | ||
1240 | } | ||
1241 | } | 1258 | } |
1242 | 1259 | ||
1243 | module_init(ivtvfb_init); | 1260 | module_init(ivtvfb_init); |