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 stmfb_ioctl(struct fb_info* fb, u_int cmd, u_long arg) { struct stmfb_info* i = (struct stmfb_info* )fb; switch (cmd) { case STMFBIO_GET_OUTPUTSTANDARDS: { struct stmfbio_outputstandards standards, *user = (void *) arg; DPRINTK("STMFBIO_GET_OUTPUTSTANDARDS\n"); if (get_user(standards.outputid, &user->outputid)) return -EFAULT; if (standards.outputid != STMFBIO_OUTPUTID_MAIN) return -EINVAL; if (down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; stmfb_get_outputstandards(i, &standards); up(&i->framebufferLock); if (put_user (standards.all_standards, &user->all_standards)) return -EFAULT; return 0; } break; case STMFBIO_GET_OUTPUTINFO: { struct stmfbio_outputinfo info, *user = (void *) arg; int ret; DPRINTK("STMFBIO_GET_OUTPUTINFO\n"); if (get_user(info.outputid, &user->outputid)) return -EFAULT; if (info.outputid != STMFBIO_OUTPUTID_MAIN) return -EINVAL; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; if (!i->current_videomode_valid) { up(&i->framebufferLock); return -EAGAIN; } ret = stmfb_videomode_to_outputinfo(&i->current_videomode, &info); up(&i->framebufferLock); if (!ret && copy_to_user ((void *) arg, &info, sizeof (info))) return -EFAULT; return ret; } break; case STMFBIO_SET_OUTPUTINFO: { struct stmfbio_outputinfo info; struct stmfb_videomode vm; int ret; DPRINTK("STMFBIO_SET_OUTPUTINFO\n"); if (copy_from_user (&info, (void *) arg, sizeof (info))) return -EFAULT; if (info.outputid != STMFBIO_OUTPUTID_MAIN) return -EINVAL; if (down_interruptible (&i->framebufferLock)) return -ERESTARTSYS; /* prevent the framebuffer kernel API from messing around w/ the config in the future, until all apps have exited */ i->fbdev_api_suspended = 1; ret = stmfb_outputinfo_to_videomode (i, &info, &vm); up (&i->framebufferLock); if (!ret) { /* * Re-create the VAR from the exact hardware description, this gives a * completely clean var, which is why we have to save and restore the * activate flags. Without this we get spurious mode changes when they * should have been just tests. */ enum _stmfbio_activate activate = info.activate; ret = stmfb_videomode_to_outputinfo (&vm, &info); info.activate = activate; if (!ret && ((activate & STMFBIO_ACTIVATE_MASK) == STMFBIO_ACTIVATE_IMMEDIATE)) ret = stmfb_set_videomode (info.outputid, &vm, i); if (!ret && copy_to_user ((void *) arg, &info, sizeof (info))) return -EFAULT; } return ret; } break; case STMFBIO_GET_PLANEMODE: { struct stmfbio_planeinfo plane, *user = (void *) arg; DPRINTK("STMFBIO_GET_PLANEMODE\n"); if (get_user (plane.layerid, &user->layerid)) return -EFAULT; if (plane.layerid != 0) return -EINVAL; if (down_interruptible (&i->framebufferLock)) return -ERESTARTSYS; if (!i->current_planeconfig_valid) { up (&i->framebufferLock); return -EAGAIN; } plane.config = i->current_planeconfig; plane.activate = STMFBIO_ACTIVATE_IMMEDIATE; up (&i->framebufferLock); if (copy_to_user ((void *) arg, &plane, sizeof (plane))) return -EFAULT; return 0; } break; case STMFBIO_SET_PLANEMODE: { struct stmfbio_planeinfo plane; int ret; DPRINTK("STMFBIO_SET_PLANEMODE\n"); if (copy_from_user (&plane, (void *) arg, sizeof (plane))) return -EFAULT; if (plane.layerid != 0) return -EINVAL; plane.config.bitdepth = stmfb_bitdepth_for_pixelformat (plane.config.format); if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; ret = stmfb_verify_planeinfo (i, &plane); up(&i->framebufferLock); if (!ret && ((plane.activate & STMFBIO_ACTIVATE_MASK) == STMFBIO_ACTIVATE_IMMEDIATE)) ret = stmfb_set_planemode (&plane, i); return ret; } break; case STMFBIO_PAN_PLANE: { struct stmfbio_plane_pan pan; int ret; DPRINTK("STMFBIO_PAN_PLANE\n"); if (copy_from_user (&pan, (void *) arg, sizeof (pan))) return -EFAULT; if (pan.layerid != 0) return -EINVAL; if (down_interruptible (&i->framebufferLock)) return -ERESTARTSYS; /* prevent the framebuffer kernel API from messing around w/ the config in the future, until all apps have exited */ i->fbdev_api_suspended = 1; ret = stmfb_set_plane_pan (&pan, i); up (&i->framebufferLock); return ret; } break; case STMFBIO_GET_VAR_SCREENINFO_EX: { DPRINTK("STMFBIO_GET_VAR_SCREENINFO_EX\n"); if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; if(copy_to_user((void*)arg,&i->current_var_ex,sizeof(struct stmfbio_var_screeninfo_ex))) { up(&i->framebufferLock); return -EFAULT; } up(&i->framebufferLock); break; } case STMFBIO_SET_VAR_SCREENINFO_EX: { struct stmfbio_var_screeninfo_ex tmp; int ret; DPRINTK("STMFBIO_SET_VAR_SCREENINFO_EX\n"); if(copy_from_user(&tmp, (void*)arg, sizeof(tmp))) return -EFAULT; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; /* * If we don't have a valid videomode, change an immediate activation to * a deferred one; the settings will take effect when the next valid video * mode is set. */ if(!i->current_planeconfig_valid && tmp.activate == STMFBIO_ACTIVATE_IMMEDIATE) tmp.activate = STMFBIO_ACTIVATE_ON_NEXT_CHANGE; ret = stmfb_set_var_ex(&tmp, i); up(&i->framebufferLock); if(ret != 0) { /* * Copy back the var to set the failed entry */ if(copy_to_user((void*)arg,&tmp, sizeof(tmp))) return -EFAULT; return ret; } break; } case STMFBIO_GET_OUTPUT_CONFIG: { struct stmfbio_output_configuration tmp; int ret; DPRINTK("STMFBIO_GET_OUTPUT_CONFIG\n"); if(copy_from_user(&tmp, (void*)arg, sizeof(tmp))) return -EFAULT; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; ret = stmfb_get_output_configuration(&tmp,i); up(&i->framebufferLock); if(ret == 0) { if(copy_to_user((void*)arg,&tmp,sizeof(tmp))) ret = -EFAULT; } return ret; } case STMFBIO_SET_OUTPUT_CONFIG: { struct stmfbio_output_configuration tmp; int ret; DPRINTK("STMFBIO_SET_OUTPUT_CONFIG\n"); if(copy_from_user(&tmp, (void*)arg, sizeof(tmp))) return -EFAULT; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; ret = stmfb_set_output_configuration(&tmp, i); up(&i->framebufferLock); if(ret != 0) { /* * Copy back the var to set the failed entry */ copy_to_user((void*)arg,&tmp, sizeof(tmp)); return ret; } break; } case STMFBIO_SET_PICTURE_CONFIG: { struct stmfbio_picture_configuration tmp; int ret; DPRINTK("STMFBIO_SET_PICTURE_CONFIG\n"); if(copy_from_user(&tmp, (void*)arg, sizeof(tmp))) return -EFAULT; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; ret = stmfb_set_picture_configuration(&tmp, i); up(&i->framebufferLock); return ret; } case STMFBIO_GET_AUXMEMORY2: { struct stmfbio_auxmem2 auxmem; if (copy_from_user (&auxmem, (void *) arg, sizeof (auxmem))) return -EFAULT; if (auxmem.index >= ARRAY_SIZE (i->AuxBase)) return -EINVAL; auxmem.physical = i->AuxBase[auxmem.index]; auxmem.size = i->AuxSize[auxmem.index]; if (copy_to_user ((void *) arg, &auxmem, sizeof (auxmem))) return -EFAULT; break; } case STMFBIO_GET_SHARED_AREA: { struct stmfbio_shared shared; shared.physical = i->ulPSharedAreaBase; shared.size = i->ulSharedAreaSize; if (copy_to_user ((void *) arg, &shared, sizeof (shared))) return -EFAULT; break; } case STMFBIO_BLT: { int ret; if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; ret = stmfbio_blt(i, arg); up(&i->framebufferLock); if(ret<0) { if(signal_pending(current)) return -ERESTARTSYS; else return ret; } break; } case STMFBIO_SET_BLITTER_PALETTE: return stmfbio_set_blitter_palette(i, arg); case STMFBIO_SYNC_BLITTER: { int err; if (!i->pBlitter) return -ENODEV; if(down_interruptible(&i->framebufferLock)) { DPRINTK(" taking framebuffer lock interrupted\n"); return -ERESTARTSYS; } if((err = stm_display_blitter_sync(i->pBlitter)) != 0) { up(&i->framebufferLock); if(signal_pending(current)) { DPRINTK(" sync interrupted\n"); return -ERESTARTSYS; } else { DPRINTK(" sync error! code = %d\n",err); return -EIO; } } up(&i->framebufferLock); break; } case STMFBIO_WAIT_NEXT: { int err; if (!i->pBlitter) return -ENODEV; if(down_interruptible(&i->framebufferLock)) { DPRINTK(" taking framebuffer lock interrupted\n"); return -ERESTARTSYS; } if((err = stm_display_blitter_waitnext(i->pBlitter)) != 0) { up(&i->framebufferLock); if(signal_pending(current)) { DPRINTK(" wait_next interrupted\n"); return -ERESTARTSYS; } else { DPRINTK(" wait_next error! code = %d\n",err); return -EIO; } } up(&i->framebufferLock); break; } case STMFBIO_GET_BLTLOAD: { if (!i->pBlitter) return -ENODEV; return put_user (stm_display_blitter_get_bltload (i->pBlitter), (unsigned long *) arg); } case STMFBIO_PRE_AUTH: return stmfbio_pre_auth(i); case STMFBIO_POST_AUTH: return stmfbio_post_auth(i, arg); case STMFBIO_WAIT_FOR_REAUTH: return stmfbio_wait_for_reauth(i, arg); case STMFBIO_SET_DAC_HD_POWER: { if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; stm_display_output_set_control(i->pFBMainOutput, STM_CTRL_DAC_HD_POWER, arg); up(&i->framebufferLock); return 0; } case STMFBIO_SET_DAC_HD_FILTER: { if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; stm_display_output_set_control(i->pFBMainOutput, STM_CTRL_DAC_HD_FILTER, arg); up(&i->framebufferLock); return 0; } case STMFBIO_SET_CGMS_ANALOG: { if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; stm_display_output_set_control(i->pFBMainOutput, STM_CTRL_CGMS_ANALOG, arg); up(&i->framebufferLock); return 0; } case FBIO_WAITFORVSYNC: { struct stmcore_display_pipeline_data *pd = *((struct stmcore_display_pipeline_data **)i->platformDevice->dev.platform_data); DPRINTK("FBIO_WAITFORVSYNC\n"); if(down_interruptible(&i->framebufferLock)) return -ERESTARTSYS; if(!i->current_videomode_valid) { up(&i->framebufferLock); return -ENODEV; } up(&i->framebufferLock); interruptible_sleep_on(&pd->display_runtime->vsync_wait_queue); if(signal_pending(current)) return -ERESTARTSYS; break; } case FBIOGET_VBLANK: { struct stmcore_display_pipeline_data *pd = *((struct stmcore_display_pipeline_data **)i->platformDevice->dev.platform_data); struct fb_vblank vblank; vblank.flags = FB_VBLANK_HAVE_COUNT; vblank.count = atomic_read (&pd->display_runtime->vsync_count); if (copy_to_user ((void *) arg, &vblank, sizeof (vblank))) return -EFAULT; break; } default: { DPRINTK(" Invalid IOCTL code 0x%08x\n",cmd); return -ENOTTY; } } return 0; }