int proc_hdmi_output_read (char *page, char **start, off_t off, int count, int *eof, void *data_unused) { int len = 0; unsigned int disabled = 0; struct stmfbio_output_configuration outputConfig = {0}; struct stmfb_info *info = NULL; mutex_lock (&(ProcDeviceContext->DvbContext->Lock)); outputConfig.outputid = 1; info = stmfb_get_fbinfo_ptr(); stmfb_get_output_configuration(&outputConfig, info); disabled = (outputConfig.hdmi_config & STMFBIO_OUTPUT_HDMI_DISABLED)?1:0; printk("%s - %u\n", __FUNCTION__, disabled); switch (disabled) { case 0: len = sprintf(page, "on\n"); break; case 1: default: len = sprintf(page, "off\n"); break; } mutex_unlock (&(ProcDeviceContext->DvbContext->Lock)); return len; }
int proc_avs_0_colorformat_read(char *page, char **start, off_t off, int count, int *eof, void *data_unused) { struct stmfb_info *info = stmfb_get_fbinfo_ptr(); struct stmfbio_output_configuration outputConfig; int len = 0; #ifdef VERY_VERBOSE printk("%s %d\n", __FUNCTION__, count); #endif outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); if (outputConfig.hdmi_config & STMFBIO_OUTPUT_HDMI_422) len = sprintf(page, "hdmi_422\n"); else if (outputConfig.hdmi_config & STMFBIO_OUTPUT_HDMI_YUV) len = sprintf(page, "hdmi_yuv\n"); else len = sprintf(page, "hdmi_rgb\n"); if (outputConfig.analogue_config & STMFBIO_OUTPUT_ANALOGUE_RGB) len += sprintf(page + len, "rgb\n"); else if (outputConfig.analogue_config & STMFBIO_OUTPUT_ANALOGUE_CVBS) len += sprintf(page + len, "cvbs\n"); else if (outputConfig.analogue_config & STMFBIO_OUTPUT_ANALOGUE_YC) len += sprintf(page + len, "svideo\n"); else if (outputConfig.analogue_config & STMFBIO_OUTPUT_ANALOGUE_YPrPb) len += sprintf(page + len, "yuv\n"); else len += sprintf(page + len, "not defined\n"); return len; }
int proc_video_videomode_read (char *page, char **start, off_t off, int count, int *eof, void *data_unused) { int len = 0; int vLoop = 0; void *fb = NULL; struct fb_info *info; #ifdef VERY_VERBOSE printk("%s\n", __FUNCTION__); #endif fb = stmfb_get_fbinfo_ptr(); /* cannot return a NULL pointer */ /* Dagobert: * dirty hack, does only work because fb->info is first param of struct stmfb_info * we should include a header here instead ... */ info = (struct fb_info*) fb; /* default */ len = sprintf(page, "pal\n"); //whithout -1 if resolution not found hangs the driver for (vLoop = 0; vLoop < (sizeof(Options) / sizeof(struct Modes)) - 1; vLoop++) { /* printk("%d\n", info->var.xres); printk("%d\n", info->var.yres); printk("%d\n", info->var.xres_virtual); printk("%d\n", info->var.yres_virtual); printk("%d\n", info->var.pixclock); printk("%d\n", info->var.left_margin); printk("%d\n", info->var.right_margin); printk("%d\n", info->var.upper_margin); printk("%d\n", info->var.lower_margin); printk("%d\n", info->var.hsync_len); printk("%d\n", info->var.vsync_len); printk("%d\n", info->var.sync); */ if (Options[vLoop].xres == info->var.xres && Options[vLoop].yres == info->var.yres && Options[vLoop].vxres == info->var.xres_virtual && Options[vLoop].vyres == info->var.yres_virtual && Options[vLoop].pixclock == info->var.pixclock && Options[vLoop].left == info->var.left_margin && Options[vLoop].right == info->var.right_margin && Options[vLoop].upper == info->var.upper_margin && Options[vLoop].lower == info->var.lower_margin && Options[vLoop].hslen == info->var.hsync_len && Options[vLoop].vslen == info->var.vsync_len && Options[vLoop].sync == info->var.sync/* && Options[vLoop].vmode == info->var.vmode*/ ) { printk("Found mode to set %s at %d\n", Options[vLoop].name, vLoop); len = sprintf(page, "%s\n", Options[vLoop].name); break; } } return len; }
int proc_hdmi_output_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; ssize_t ret = -ENOMEM; struct stmfbio_output_configuration outputConfig = {0}; struct stmfb_info *info = NULL; char* myString = kmalloc(count + 1, GFP_KERNEL); printk("%s %ld - ", __FUNCTION__, count); mutex_lock (&(ProcDeviceContext->DvbContext->Lock)); page = (char *)__get_free_page(GFP_KERNEL); if (page) { ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; strncpy(myString, page, count); myString[count] = '\0'; printk("%s\n", myString); outputConfig.outputid = 1; info = stmfb_get_fbinfo_ptr(); stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.analogue_config = 0; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_HDMI_CONFIG; if (!strncmp("off", myString, count)) { outputConfig.hdmi_config |= STMFBIO_OUTPUT_HDMI_DISABLED; } else if (!strncmp("on", myString, count)) { outputConfig.hdmi_config &= ~STMFBIO_OUTPUT_HDMI_DISABLED; } stmfb_set_output_configuration(&outputConfig, info); /* always return count to avoid endless loop */ ret = count; } out: free_page((unsigned long)page); kfree(myString); mutex_unlock (&(ProcDeviceContext->DvbContext->Lock)); return ret; }
int proc_video_alpha_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; char *myString; ssize_t ret = -ENOMEM; /* int result; */ #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif page = (char *)__get_free_page(GFP_KERNEL); if (page) { struct stmfb_info *info = stmfb_get_fbinfo_ptr(); struct stmfbio_var_screeninfo_ex varEx; int err = 0; int alpha = 0; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; myString = (char *) kmalloc(count + 1, GFP_KERNEL); strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif sscanf(myString, "%d", &alpha); varEx.layerid = 0; varEx.caps = 0; varEx.activate = 0; //STMFBIO_ACTIVATE_IMMEDIATE; varEx.caps |= STMFBIO_VAR_CAPS_OPACITY; varEx.opacity = alpha; err = stmfb_set_var_ex(&varEx, info); kfree(myString); } ret = count; out: free_page((unsigned long)page); return ret; }
int proc_vmpeg_0_dst_left_read (char *page, char **start, off_t off, int count, int *eof, void *data) { int len = 0; int l, t, w, h; int err, x, y; void *fb; struct fb_info *info; struct fb_var_screeninfo screen_info; struct DeviceContext_s *pContext = (struct DeviceContext_s*)data; #ifdef VERY_VERBOSE printk("%s\n", __FUNCTION__); #endif fb = stmfb_get_fbinfo_ptr(); info = (struct fb_info*) fb; memcpy(&screen_info, &info->var, sizeof(struct fb_var_screeninfo)); if (fb != NULL) { y = screen_info.yres; x = screen_info.xres; } else { y = 576; x = 720; } if (pContext != NULL) { mutex_lock (&(pContext->DvbContext->Lock)); err = StreamGetOutputWindow(pContext->VideoStream, &l, &t, &w, &h); if (err != 0) printk("failed to get output window %d\n", err); #ifdef VERY_VERBOSE else printk("get output window to %d %d %d, %d ok\n", l, t, w, h); #endif mutex_unlock (&(pContext->DvbContext->Lock)); } len = sprintf(page, "%x\n", 720*l/x); return len; }
int proc_video_hdmi_colorspace_read(char *page, char **start, off_t off, int count, int *eof, void *data_unused) { struct stmfb_info *info = stmfb_get_fbinfo_ptr(); struct stmfbio_output_configuration outputConfig; int len = 0; printk("%s %d\n", __FUNCTION__, count); outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); if (outputConfig.hdmi_config & STMFBIO_OUTPUT_HDMI_422) len = sprintf(page, "hdmi_422\n"); else if (outputConfig.hdmi_config & STMFBIO_OUTPUT_HDMI_YUV) len = sprintf(page, "hdmi_yuv\n"); else len = sprintf(page, "hdmi_rgb\n"); return len; }
int proc_video_alpha_read(char* page, char** start, off_t off, int count, int* eof, void* data_unused) { int len = 0; #ifdef VERY_VERBOSE printk("%s\n", __FUNCTION__); #endif #if !defined(ADB_BOX) struct stmfb_info* info = stmfb_get_fbinfo_ptr(); struct stmfbio_var_screeninfo_ex varEx; stmfb_get_var_ex(&varEx, info); len = sprintf(page, "%d\n", varEx.opacity); #endif #if defined(ADB_BOX) len = sprintf(page, "0\n"); #endif return len; }
int proc_video_pal_v_end_read(char* page, char** start, off_t off, int count, int* eof, void* data_unused) { int len = 0; void* fb = NULL; struct fb_info* info; #ifdef VERY_VERBOSE printk("%s\n", __FUNCTION__); #endif fb = stmfb_get_fbinfo_ptr(); /* cannot return a NULL pointer */ /* * dirty hack, does only work because fb->info is first param of struct stmfb_info * we should include a header here instead ... */ info = (struct fb_info*) fb; len = sprintf(page, "%X\n", info->var.lower_margin); return len; }
int proc_vmpeg_0_dst_top_read (char *page, char **start, off_t off, int count, int *eof, void *data) { int len = 0; int l=0,t=0,w,h; int err, x=720, y=576; void* fb; struct fb_info *info; struct fb_var_screeninfo screen_info; struct DeviceContext_s *pContext = (struct DeviceContext_s*)data; printk("%s\n", __FUNCTION__); fb = stmfb_get_fbinfo_ptr(); info = (struct fb_info*) fb; if (fb != NULL) { memcpy(&screen_info, &info->var, sizeof(struct fb_var_screeninfo)); y=screen_info.yres; x=screen_info.xres; } if (pContext != NULL) { mutex_lock (&(pContext->DvbContext->Lock)); err = DvbStreamGetOutputWindow(pContext->VideoStream, &l,&t,&w,&h); mutex_unlock (&(pContext->DvbContext->Lock)); if (err != 0) printk("failed to get output window %d\n", err); else printk("get output window to %d %d %d, %d ok\n", l, t, w, h); len = sprintf(page, "%x\n", 576*t/y); } return len; }
int proc_vmpeg_0_dst_all_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; ssize_t ret = -ENOMEM; int err, x, y; void* fb; struct fb_info *info; struct fb_var_screeninfo screen_info; char* myString = kmalloc(count + 1, GFP_KERNEL); struct DeviceContext_s *pContext = (struct DeviceContext_s*)data; #ifdef VERY_VERBOSE printk("%s %d - ", __FUNCTION__, (unsigned int)count); #endif fb = stmfb_get_fbinfo_ptr(); info = (struct fb_info*) fb; memcpy(&screen_info, &info->var, sizeof(struct fb_var_screeninfo)); if (fb != NULL) { y = screen_info.yres; x = screen_info.xres; } else { y = 576; x = 720; } page = (char *)__get_free_page(GFP_KERNEL); if (page) { int l, t, w, h; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif sscanf(myString, "%x %x %x %x", &l ,&t, &w, &h); #ifdef VERY_VERBOSE printk("%x, %x, %x, %x\n", l, t, w, h); #endif if (pContext != NULL) { mutex_lock (&(pContext->DvbContext->Lock)); h = y*h/576; w = x*w/720; l = x*l/720; t = y*t/576; #ifdef VERY_VERBOSE printk("%x, %x, %x, %x\n", l, t, w, h); #endif err = DvbStreamSetOutputWindow(pContext->VideoStream, l, t, w, h); if (err != 0) printk("failed to set output window %d\n", err); #ifdef VERY_VERBOSE else printk("set output window ok %d %d %d %d\n", l, t, w, h); #endif mutex_unlock (&(pContext->DvbContext->Lock)); } /* always return count to avoid endless loop */ ret = count; } out: free_page((unsigned long)page); kfree(myString); return ret; }
int proc_video_hdmi_colorspace_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; char *myString; ssize_t ret = -ENOMEM; #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif page = (char *)__get_free_page(GFP_KERNEL); if (page) { struct stmfb_info *info = stmfb_get_fbinfo_ptr(); struct stmfbio_output_configuration outputConfig; int err = 0; //int alpha = 0; int hdmi_colour = 0; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; myString = (char *) kmalloc(count + 1, GFP_KERNEL); strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif //sscanf(myString, "%d", &alpha); //0rgb 1yuv 2422 if (strncmp("hdmi_rgb", page, count - 1) == 0) { hdmi_colour = 0; } else if (strncmp("hdmi_yuv", page, count - 1) == 0) { hdmi_colour = 1; } else if (strncmp("hdmi_422", page, count - 1) == 0) { hdmi_colour = 2; } outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = 0; //STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_HDMI_CONFIG; outputConfig.hdmi_config &= ~(STMFBIO_OUTPUT_HDMI_YUV | STMFBIO_OUTPUT_HDMI_422); switch (hdmi_colour) { case 1: outputConfig.hdmi_config |= STMFBIO_OUTPUT_HDMI_YUV; break; case 2: outputConfig.hdmi_config |= (STMFBIO_OUTPUT_HDMI_YUV | STMFBIO_OUTPUT_HDMI_422); break; default: break; } err = stmfb_set_output_configuration(&outputConfig, info); //if(ioctl(fbfd, STMFBIO_SET_OUTPUT_CONFIG, &outputConfig)<0) //perror("setting output configuration failed"); kfree(myString); } ret = count; out: free_page((unsigned long)page); return ret; }
int proc_avs_0_colorformat_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; char *myString; ssize_t ret = -ENOMEM; #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif page = (char *)__get_free_page(GFP_KERNEL); if (page) { struct stmfb_info *info = stmfb_get_fbinfo_ptr(); struct stmfbio_output_configuration outputConfig; int err = 0; int alpha = 0; int hdmi_colour = 0; int scart_colour = 0; int hdmi0scart1yuv2 = 1; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; myString = (char *) kmalloc(count + 1, GFP_KERNEL); strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif sscanf(myString, "%d", &alpha); //0rgb 1yuv 2422 if (strncmp("hdmi_rgb", page, count - 1) == 0) { hdmi_colour = 0; hdmi0scart1yuv2 = 0; } else if (strncmp("hdmi_yuv", page, count - 1) == 0) { hdmi_colour = 1; hdmi0scart1yuv2 = 0; } else if (strncmp("hdmi_422", page, count - 1) == 0) { hdmi_colour = 2; hdmi0scart1yuv2 = 0; } else if (strncmp("rgb", page, count - 1) == 0) { scart_colour = SAA_MODE_RGB; hdmi0scart1yuv2 = 1; } else if (strncmp("cvbs", page, count - 1) == 0) { scart_colour = SAA_MODE_FBAS; hdmi0scart1yuv2 = 1; } else if (strncmp("svideo", page, count - 1) == 0) { scart_colour = SAA_MODE_SVIDEO; hdmi0scart1yuv2 = 1; } else if (strncmp("yuv", page, count - 1) == 0) { hdmi0scart1yuv2 = 2; } if (hdmi0scart1yuv2 == 0) { outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = 0; //STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_HDMI_CONFIG; outputConfig.hdmi_config &= ~(STMFBIO_OUTPUT_HDMI_YUV | STMFBIO_OUTPUT_HDMI_422); switch (hdmi_colour) { case 1: outputConfig.hdmi_config |= STMFBIO_OUTPUT_HDMI_YUV; break; case 2: outputConfig.hdmi_config |= (STMFBIO_OUTPUT_HDMI_YUV | STMFBIO_OUTPUT_HDMI_422); break; default: break; } err = stmfb_set_output_configuration(&outputConfig, info); } else if (hdmi0scart1yuv2 == 1) { avs_command_kernel(SAAIOSMODE, (void *) scart_colour); outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = 0; //STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_ANALOGUE_CONFIG; outputConfig.analogue_config = 0; switch (scart_colour) { case SAA_MODE_RGB: outputConfig.analogue_config |= (STMFBIO_OUTPUT_ANALOGUE_RGB | STMFBIO_OUTPUT_ANALOGUE_CVBS); break; case SAA_MODE_FBAS: outputConfig.analogue_config |= STMFBIO_OUTPUT_ANALOGUE_CVBS; break; case SAA_MODE_SVIDEO: outputConfig.analogue_config |= STMFBIO_OUTPUT_ANALOGUE_YC; break; default: break; } err = stmfb_set_output_configuration(&outputConfig, info); if (err != 0) { printk("SET SCART COLOR - %ld - ", count); } } else { outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = 0; //STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_ANALOGUE_CONFIG; outputConfig.analogue_config = 0; outputConfig.analogue_config |= STMFBIO_OUTPUT_ANALOGUE_YPrPb; err = stmfb_set_output_configuration(&outputConfig, info); if (err != 0) { printk("SET SCART COLOR - %ld - ", count); } } //if(ioctl(fbfd, STMFBIO_SET_OUTPUT_CONFIG, &outputConfig)<0) //perror("setting output configuration failed"); kfree(myString); } ret = count; out: free_page((unsigned long)page); return ret; }
int proc_avs_0_input_write(struct file *file, const char __user *buf, unsigned long count, void *data) { char *page; char *myString; ssize_t ret = -ENOMEM; /* int result; */ #if defined(ADB_BOX) struct stmfbio_output_configuration outputConfig; struct stmfb_info *info = stmfb_get_fbinfo_ptr(); int err; outputConfig.outputid = 1; stmfb_get_output_configuration(&outputConfig, info); outputConfig.caps = 0; outputConfig.activate = 0;//STMFBIO_ACTIVATE_IMMEDIATE; outputConfig.analogue_config = 0; outputConfig.caps |= STMFBIO_OUTPUT_CAPS_HDMI_CONFIG; #endif #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif page = (char *)__get_free_page(GFP_KERNEL); if (page) { ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; myString = (char *) kmalloc(count + 1, GFP_KERNEL); strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif if (!strncmp("encoder", myString, count - 1)) { avs_command_kernel(SAAIOSSRCSEL, SAA_SRC_ENC); // Note: Volumne is not changed directly but by using the MIXER instead of the AVS. // So this should always be set to the maximum #if defined(UFS910) \ || defined(ADB_BOX) avs_command_kernel(AVSIOSVOL, (void *) 31); #else avs_command_kernel(AVSIOSVOL, (void *) 0); #endif #if defined(ADB_BOX) avs_command_kernel(SAAIOSWSS, (void *) SAA_WSS_43F); outputConfig.hdmi_config &= ~STMFBIO_OUTPUT_HDMI_DISABLED; #endif current_input = ENCODER; } if (!strncmp("scart", myString, count - 1)) { avs_command_kernel(SAAIOSSRCSEL, (void *) SAA_SRC_SCART); avs_command_kernel(AVSIOSVOL, (void *) current_volume); #if defined(ADB_BOX) avs_command_kernel(SAAIOSWSS, (void *) SAA_WSS_OFF); outputConfig.hdmi_config |= STMFBIO_OUTPUT_HDMI_DISABLED; #endif current_input = SCART; } #if defined(ADB_BOX) err = stmfb_set_output_configuration(&outputConfig, info); if (err != 0) { printk("HDMI Config Disabled - Failed !!!!!!!!!!"); } #endif kfree(myString); //result = sscanf(page, "%3s %3s %3s %3s %3s", s1, s2, s3, s4, s5); } ret = count; out: free_page((unsigned long)page); return ret; }
int proc_video_pal_h_start_write(struct file* file, const char __user* buf, unsigned long count, void* data) { char* page; ssize_t ret = -ENOMEM; /* int result; */ int value; char* myString = kmalloc(count + 1, GFP_KERNEL); #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif mutex_lock(&(ProcDeviceContext->DvbContext->Lock)); page = (char*)__get_free_page(GFP_KERNEL); if (page) { void* fb; struct fb_info* info; struct fb_var_screeninfo screen_info; int createNew = 0; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; strncpy(myString, page, count); myString[count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif sscanf(myString, "%x", &value); fb = stmfb_get_fbinfo_ptr(); info = (struct fb_info*) fb; memcpy(&screen_info, &info->var, sizeof(struct fb_var_screeninfo)); if (fb != NULL) { int err; /* otherwise we got EBUSY from stmfb device */ /* Dagobert: Bugfix: "demux stop" bug; ticket #10 */ if (ProcDeviceContext != NULL) { if (ProcDeviceContext->VideoState.play_state != VIDEO_STOPPED) VideoIoctlStop(ProcDeviceContext, 1); if (isDisplayCreated(BACKEND_VIDEO_ID, ProcDeviceContext->Id)) { createNew = 1; #ifdef VERY_VERBOSE printk("delete display\n"); #endif DvbDisplayDelete(BACKEND_VIDEO_ID, ProcDeviceContext->Id); } } info->flags |= FBINFO_MISC_USEREVENT; screen_info.left_margin = value; err = fb_set_var(fb, &screen_info); if (err != 0) printk("error setting new resolution %d\n", err); if ((ProcDeviceContext != NULL) && (createNew == 1)) { #ifdef VERY_VERBOSE printk("create new display\n"); #endif DisplayCreate(BACKEND_VIDEO_ID, ProcDeviceContext->Id); VideoIoctlPlay(ProcDeviceContext); err = DvbStreamSetOutputWindow(ProcDeviceContext->VideoStream, 0, 0, screen_info.xres, screen_info.yres); if (err != 0) { printk("failed to set output window %d, %d, %d\n", screen_info.xres, screen_info.yres, err); } #ifdef VERY_VERBOSE else printk("set output window to %d, %d ok\n", screen_info.xres, screen_info.yres); #endif } } else { printk("Cannot get stmfb_info struct\n"); } /* always return count to avoid endless loop */ ret = count; } out: free_page((unsigned long)page); kfree(myString); mutex_unlock(&(ProcDeviceContext->DvbContext->Lock)); return ret; }
/* hack hack ;-) */ int proc_video_videomode_write(struct file* file, const char __user* buf, unsigned long count, void* data) { char* page; ssize_t ret = -ENOMEM; /* int result; */ int vLoop; int new_count; char* myString = kmalloc(count + 1, GFP_KERNEL); void* fb; struct fb_info *info; #ifdef VERY_VERBOSE printk("%s %ld - ", __FUNCTION__, count); #endif mutex_lock(&(ProcDeviceContext->DvbContext->Lock)); fb = stmfb_get_fbinfo_ptr(); info = (struct fb_info*) fb; page = (char*)__get_free_page(GFP_KERNEL); if (page) { int modeToSet = -1; int aktmode = -1; ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; /* Dagobert: echo add a \n which will be counted as a char */ if (page[count - 1] == '\n') new_count = count - 1; else new_count = count; strncpy(myString, page, new_count); myString[new_count] = '\0'; #ifdef VERY_VERBOSE printk("%s\n", myString); #endif //whithout -1 write a unsupportet string hangs the driver for (vLoop = 0; vLoop < (sizeof(Options) / sizeof(struct Modes)) - 1; vLoop++) { if (Options[vLoop].xres == info->var.xres && Options[vLoop].yres == info->var.yres && Options[vLoop].vxres == info->var.xres_virtual && Options[vLoop].vyres == info->var.yres_virtual && Options[vLoop].pixclock == info->var.pixclock && Options[vLoop].left == info->var.left_margin && Options[vLoop].right == info->var.right_margin && Options[vLoop].upper == info->var.upper_margin && Options[vLoop].lower == info->var.lower_margin && Options[vLoop].hslen == info->var.hsync_len && Options[vLoop].vslen == info->var.vsync_len && Options[vLoop].sync == info->var.sync/* && Options[vLoop].vmode == info->var.vmode*/) { aktmode = vLoop; } if (strncmp(myString, Options[vLoop].name, new_count) == 0) { printk("Found mode to set %s at %d\n", Options[vLoop].name, vLoop); modeToSet = vLoop; } } if (aktmode == modeToSet) modeToSet = -1; if (modeToSet != -1) { struct fb_var_screeninfo screen_info; int createNew = 0; memcpy(&screen_info, &info->var, sizeof(struct fb_var_screeninfo)); if (fb != NULL) { int err; /* otherwise we got EBUSY from stmfb device */ /* Dagobert: Bugfix: "demux stop" bug; ticket #10 */ if (ProcDeviceContext != NULL) { if (ProcDeviceContext->VideoState.play_state != VIDEO_STOPPED) VideoIoctlStop(ProcDeviceContext, 1); if (isDisplayCreated(BACKEND_VIDEO_ID, ProcDeviceContext->Id)) { createNew = 1; #ifdef VERY_VERBOSE printk("delete display\n"); #endif DvbDisplayDelete(BACKEND_VIDEO_ID, ProcDeviceContext->Id); } } info->flags |= FBINFO_MISC_USEREVENT; screen_info.xres = Options[modeToSet].xres; /* visible resolution */ screen_info.yres = Options[modeToSet].yres; screen_info.xres_virtual = Options[modeToSet].vxres; /* virtual resolution */ screen_info.yres_virtual = Options[modeToSet].vyres; screen_info.pixclock = Options[modeToSet].pixclock; screen_info.left_margin = Options[modeToSet].left; screen_info.right_margin = Options[modeToSet].right; screen_info.upper_margin = Options[modeToSet].upper; screen_info.lower_margin = Options[modeToSet].lower; screen_info.hsync_len = Options[modeToSet].hslen; screen_info.vsync_len = Options[modeToSet].vslen; screen_info.sync = Options[modeToSet].sync; screen_info.vmode = Options[modeToSet].vmode; screen_info.activate = FB_ACTIVATE_FORCE; err = fb_set_var(fb, &screen_info); if (err != 0) printk("error setting new resolution %d\n", err); if ((ProcDeviceContext != NULL) && (createNew == 1)) { #ifdef VERY_VERBOSE printk("create new display\n"); #endif DisplayCreate(BACKEND_VIDEO_ID, ProcDeviceContext->Id); VideoIoctlPlay(ProcDeviceContext); err = DvbStreamSetOutputWindow(ProcDeviceContext->VideoStream, 0, 0, Options[modeToSet].xres, Options[modeToSet].yres); if (err != 0) { printk("failed to set output window %d, %d, %d\n", Options[modeToSet].xres, Options[modeToSet].yres, err); } #ifdef VERY_VERBOSE else printk("set output window to %d, %d ok\n", Options[modeToSet].xres, Options[modeToSet].yres); #endif } } else { printk("Cannot get stmfb_info struct\n"); } } /* always return count to avoid endless loop */ ret = count; } out: free_page((unsigned long)page); kfree(myString); mutex_unlock(&(ProcDeviceContext->DvbContext->Lock)); return ret; }