Beispiel #1
0
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;
}
Beispiel #2
0
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;
}