aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtvfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtvfb.c')
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c91
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
1192static 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
1207static 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
1191static int __init ivtvfb_init(void) 1226static 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, &registered, 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
1221static void ivtvfb_cleanup(void) 1248static 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
1243module_init(ivtvfb_init); 1260module_init(ivtvfb_init);