コード例 #1
0
static int sfh7743_misc_ioctl(struct inode *inode, struct file *file,
                              unsigned int cmd, unsigned long arg)
{
    void __user *argp = (void __user *)arg;
    u8 enable;
    struct sfh7743_data *sfh = file->private_data;

    switch (cmd) {
    case SFH7743_IOCTL_SET_ENABLE:
        if (copy_from_user(&enable, argp, 1))
            return -EFAULT;
        if (enable > 1)
            return -EINVAL;

        if (enable != 0)
            sfh7743_enable(sfh);
        else
            sfh7743_disable(sfh);

        break;

    case SFH7743_IOCTL_GET_ENABLE:
        enable = atomic_read(&sfh->enabled);
        if (copy_to_user(argp, &enable, 1))
            return -EINVAL;

        break;

    default:
        return -EINVAL;
    }

    return 0;
}
コード例 #2
0
static int sfh7743_resume(struct platform_device *pdev)
{
    struct sfh7743_data *sfh = platform_get_drvdata(pdev);

    if (sfh->on_before_suspend)
        return sfh7743_enable(sfh);
    return 0;
}
コード例 #3
0
static int sfh7743_fops_write (struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	if ( count > 3 )
	      return -EINVAL;
	if (copy_from_user(writeBuf, buf, count))
		return -EINVAL;
	/* If disable requested */
	if ( !(strncmp(writeBuf, "0", 1 ) ) )
	{
		sfh7743_enable(false);
	}
	/* If enable requested */
	else
	{
		sfh7743_enable(true);
	}
   return E_OK;
} /* End sfh7743_fops_write */
コード例 #4
0
/*!
 * @brief Logs data
 *
 * This function is called to set the current mode (Enabled/Disabled) of
 * of the proximity device
 *
 */
static ssize_t sfh7743_set_mode(struct device *dev, struct device_attribute *att, const char *buf, size_t count)
{
	/* If disable requested */
	if ( !(strncmp(buf, "0", 1 ) ) )
	{
		sfh7743_enable(false);
	}
	/* If enable requested */
	else
	{
#ifdef CONFIG_MACH_MOT
#if 0
		if (machine_is_motus() &&  (mot_hw_rev < 0x2F)) {
			sfh7743_log(KERN_ERR "PROXIMITY SENSOR NOT"
				"ENABLED FOR MOTUS P2 BOARDS (< 2F)\n");
			return 0;
	}
#endif
#endif
		sfh7743_enable(true);
	}
	return 0;
}
コード例 #5
0
static int	sfh7743_probe(struct platform_device *pdev)
{
   /* Initialize error condition to no-error */
   int error = E_OK;

   sfh7743_log(KERN_INFO "sfh7743_probe: Enter....\n");
   /* Initialize input device */
   sfh7743_info.idev = NULL;
   /* Initialize interrupt values */
   sfh7743_info.gpio_intr = -1;
   sfh7743_info.gpio_en = -1;
#ifndef CONFIG_MACH_MOT
   sfh7743_info.vreg_name = NULL;
   sfh7743_info.vreg_en = NULL;
#endif
   sfh7743_info.irq = -1;
	sfh7743_info.state = 0;

   /* Register IR prox device */
   error = sfh7743_register();
   if (error == E_OK)
   {
      /* Initialize the work queue */
      INIT_WORK (&sfh7743_info.wq, sfh7743_irq_bottom_half);

      /* GPIOs and IRQ config */
      error = sfh7743_config_int(pdev);
      if (error == E_OK)
      {
         /* Enable proximity sensor */
         sfh7743_enable(false);
      }
      else
      {
         /* Unregistered what was previously registered */
         sfh7743_unregister();
			return error;
      }
   }

   /* Report init status to log */
   if (error == E_OK) {
#ifdef CONFIG_MACH_MOT
	sfh7743_log(KERN_INFO "sfh7743_probe: initialized gpio_int[%d]"
		"irq[%d] gpio_en[%d]\n", sfh7743_info.gpio_intr,
			sfh7743_info.irq, sfh7743_info.gpio_en);
#else
	sfh7743_log(KERN_INFO "sfh7743_probe: initialized gpio_int[%d]"
		"irq[%d] gpio_en[%d] vreg_en[%s]\n", sfh7743_info.gpio_intr,
			sfh7743_info.irq, sfh7743_info.gpio_en,
				sfh7743_info.vreg_name);
#endif
   }
   else
   {
      sfh7743_log(KERN_ERR "sfh7743_probe: initialization failed: %d\n", error);
   }

	if ( (error = sysfs_create_group(&(pdev->dev.kobj), &sfh7743_attr_group) ))
	{
		sfh7743_log(KERN_INFO "sfh7743_probe: Exit....\n");
	}
   return error;
}
コード例 #6
0
/** \fn static int sfh7743_config_int (void)
 *  \brief Configure sfh7743 sensor interrupt GPIOs and routine
 *  \return E_OK if successful, -1 if any failure occurred
 */
static int sfh7743_config_int (struct platform_device *pdev)
{
	struct	sfh7743_platform_data	*pdata = pdev->dev.platform_data;

   /* Initialize error condition to no-error */
   int error = E_OK;

	if ( !pdata )
		return -EBUSY;

   /* Read interrupt numbers from hardware config */
   sfh7743_info.gpio_intr = pdata->gpio_intr;
   sfh7743_info.gpio_en   = pdata->gpio_en;
#ifndef CONFIG_MACH_MOT
   sfh7743_info.vreg_name = pdata->vreg_en;
#endif

   /* Ensure proper pin numbers are returned */
#ifdef CONFIG_MACH_MOT

   if ((sfh7743_info.gpio_intr < 0) || (sfh7743_info.gpio_en < 0)) {
	sfh7743_log(KERN_ERR "sfh7743_config_int: get_gpio failure\n");
#else
   if ((sfh7743_info.gpio_intr<0) || ((sfh7743_info.gpio_en<0)&&(pdata->vreg_en==NULL)))
   {
      sfh7743_log(KERN_ERR "sfh7743_config_int: get_gpio/vreg_get failure\n");
#endif
      goto sfh7743_error;
   }

   /* Configure change interrupt */
   if (gpio_request(sfh7743_info.gpio_intr, SFH7743_MODULE_NAME) == E_OK)
   {
      /* Set gpio to input direction to allow irq signals */
      if (gpio_direction_input(sfh7743_info.gpio_intr) != E_OK)
      {
         sfh7743_log(KERN_ERR "sfh7743_config_int: gpio_int direction error\n");
         goto sfh7743_error_gpio_int_requested;
      }
   }
   else
   {
      sfh7743_log(KERN_ERR "sfh7743_config_int: gpio_request error\n");
      goto sfh7743_error;
   }


   /* Record irq value to structure.  A negative value indicates an error */
   sfh7743_info.irq = gpio_to_irq(sfh7743_info.gpio_intr);
   /* Attempt setup of interrupt request handler if proper irq returned above.
    * If either fails, indicate and exit */
   if ( (sfh7743_info.irq<0) ||
        (request_irq(sfh7743_info.irq, sfh7743_irq_handler,IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_SHARED,
                      SFH7743_MODULE_NAME, &sfh7743_info) != E_OK) )
   {
      sfh7743_log(KERN_ERR "sfh7743_config_int: irq request error\n");
      goto sfh7743_error_gpio_int_requested;
   }
#ifdef CONFIG_MACH_MOT
	set_irq_wake(sfh7743_info.irq, 1);
#else
   if (sfh7743_info.gpio_en < 0) 
   {
      sfh7743_info.vreg_en = vreg_get(0, sfh7743_info.vreg_name);
      goto sfh7743_no_cleanup;
   }
#endif

   /* Configure enable interrupt */
   if (gpio_request(sfh7743_info.gpio_en, SFH7743_MODULE_NAME) == E_OK)
   {
      /* Set gpio to output direction to allow irq signals */
      if (gpio_direction_output(sfh7743_info.gpio_en,0) == E_OK)
      {
         /* This is a "total success" condition, so the function is exited */
         goto sfh7743_no_cleanup;
		}
      else
      {
         sfh7743_log(KERN_ERR "sfh7743_config_int: direction error\n");
         goto sfh7743_error_gpio_en_requested;
      }
   }
   else
   {
      sfh7743_log(KERN_ERR "sfh7743_config_int: gpio_request error\n");
      goto sfh7743_error_irq_requested;
   }

   /* Naturally flowing into this destruction is impossible */
sfh7743_error_gpio_en_requested:
   gpio_free (sfh7743_info.gpio_en);

sfh7743_error_irq_requested:
#ifdef CONFIG_MACH_MOT
	set_irq_wake(sfh7743_info.irq, 0);
#endif
	free_irq(sfh7743_info.irq, 0);

sfh7743_error_gpio_int_requested:
   gpio_free(sfh7743_info.gpio_intr);

sfh7743_error:
   sfh7743_info.gpio_intr = -1;
   sfh7743_info.gpio_en = -1;
#ifndef CONFIG_MACH_MOT
   sfh7743_info.vreg_name = NULL;
   sfh7743_info.vreg_en = NULL;
#endif
   sfh7743_info.irq = -1;
   error = -1;

sfh7743_no_cleanup:
   return error;
}

/** \fn void __exit sfh7743_exit (void)
 *  \brief sfh7743 driver cleanup function, called when the driver is destroyed
 *  \return void
 */
void __exit sfh7743_exit (void)
{
   /* Disable proximity sensor */
   sfh7743_enable(false);

   /* Free irq */
   if (sfh7743_info.irq != -1)
   {
#ifdef CONFIG_MACH_MOT
		set_irq_wake(sfh7743_info.irq, 0);
#endif
		free_irq(sfh7743_info.irq, 0);
   }
   /* Free GPIOs */
   if (sfh7743_info.gpio_intr != -1)
   {
      gpio_free(sfh7743_info.gpio_intr);
   }
   if (sfh7743_info.gpio_en != -1)
   {
      gpio_free(sfh7743_info.gpio_en);
   }

   /* prox_ir unregister */
   if (sfh7743_info.idev)
   {
      sfh7743_unregister();
   }
}
コード例 #7
0
/** \fn static int sfh7743_fops_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
 *  \brief System response point to fop ioctl
 *  \return Error code where zero indicates no-error, or value depending on ioctl call
 */
static int sfh7743_fops_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
   /** \var error
    *  \brief Return error code, initialized to no error
    */
   int error = E_OK;
   /* Temporary store */
   long tmp_var;
	uint8_t	enable;
	void __user *argp = (void __user *)arg;

   /* Process the parameter command */
   switch (cmd)
   {
      case SFH7743_IOCTL_GET_PRESENCE:
        /* Get/return distance */
		/* if devise is disable, return 0 */
		if ( sfh7743_info.state )
		{
			sfh7743_log(KERN_INFO "sfh7743_fops_ioctl: device is enabled\n");
			sfh7743_get_distance(&tmp_var);
			sfh7743_log(KERN_INFO "sfh7743_fops_ioctl: Distance value: %d\n",tmp_var);
		}
		else
		{
			sfh7743_log(KERN_INFO "sfh7743_fops_ioctl: device is disabled\n");
			tmp_var = 0;
		}
		error = tmp_var;
/*
		error = copy_to_user(&arg, &tmp_var,sizeof(tmp_var));
		if ( error != 0 )
		{
			sfh7743_log(KERN_INFO "sfh7743_fops_ioctl: Could not copy %d bytes to user space.\n",error);
		}
*/
		break;
      case SFH7743_IOCTL_PUSH_PRESENCE:
         /* Get/push-to-input distance */
         sfh7743_get_distance(&tmp_var);
         sfh7743_post_data(tmp_var);
         break;
      case SFH7743_IOCTL_SET_ENABLE:
		if (copy_from_user(&enable, argp, 1))
			return -EFAULT;
		if (enable > 1)
			return -EINVAL;

		if (enable != 0)
			sfh7743_enable(true);
		else
			sfh7743_enable(false);
         break;

		 case SFH7743_IOCTL_ENABLE:
		 /* Disable proximity sensor */
		 sfh7743_enable(true); 	   
		 break;
		 
		 case SFH7743_IOCTL_DISABLE:
		 /* Disable proximity sensor */
		 sfh7743_enable(false); 	   
		 break;
		 
      case SFH7743_IOCTL_GET_ENABLE:
#ifdef CONFIG_MACH_MOT
		enable = gpio_get_value(sfh7743_info.gpio_en);
		if (copy_to_user(argp, &enable, 1))
			return -EINVAL;
#else
         error = sfh7743_info.state;
#endif
		   break;
	  
      case SFH7743_IOCTL_GET_STATUS:
           error = sfh7743_info.state;
      break;

      default:
         sfh7743_log(KERN_ERR "sfh7743: invalid ioctl cmd supplied\n");
         /* Indicate inappropriate ioctl for device */
         error = -ENOTTY;
         break;
   } /* End switch (cmd) */

   return error;
} /* End sfh7743_fops_ioctl */
コード例 #8
0
int sfh7743_input_open(struct input_dev *input)
{
    struct sfh7743_data *sfh = input_get_drvdata(input);

    return sfh7743_enable(sfh);
}