static int ltr558_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
    int ret = 0;
	  struct ltr558_info *lpi;
	  struct ltr558_platform_data *pdata;

	  D("[ltr558] %s\n", __func__);


	  lpi = kzalloc(sizeof(struct ltr558_info), GFP_KERNEL);
	  if (!lpi)
        return -ENOMEM;

	/*D("[ltr558] %s: client->irq = %d\n", __func__, client->irq);*/

	  lpi->i2c_client = client;
	  pdata = client->dev.platform_data;
	  if (!pdata) {
		    pr_err("[ltr558 error]%s: Assign platform_data error!!\n",__func__);
		    ret = -EBUSY;
		    goto err_platform_data_null;
	  }
    /*start to declare regulator and enable power*/
    lpi->ls_regulator = regulator_get(NULL, "hcldo1_3v3");
	  if (!lpi->ls_regulator || IS_ERR(lpi->ls_regulator)) {
		    printk(KERN_ERR "ltr558 No Regulator available\n");
		    ret = -EFAULT;
		    goto err_platform_data_null;
	  }
    
    if(lpi->ls_regulator){
            regulator_set_voltage(lpi->ls_regulator,3300000,3300000);
            regulator_enable(lpi->ls_regulator);/*enable power*/
    }
//[email protected] 2011.12.21 begin
//check device ID
      uint8_t device_id = 0;
	  ret = ltr558_i2c_read(LTR558_MANUFACTURER_ID,&device_id);
	  if((device_id == 0x05)||(!ret))
	  {
	  	   printk("=====ltr558 device found!!====\n");
	  }
	  else
	  {
	 	   printk("ltr558 device no found error!! id = %x\n",device_id);
		   goto err_platform_data_null;
	  }
	  
//[email protected] 2011.12.21 end


	  lpi->irq = client->irq;
	  i2c_set_clientdata(client, lpi);
          //ltr558_devinit();
         // if (ret) {
          //      printk("ltr558 device init failed.\n");
          
          //}
          pdata->init();/*init sensor gpio interrupt pin*/

	  lp_info = lpi;

	  mutex_init(&als_enable_mutex);
	  mutex_init(&als_disable_mutex);
	  mutex_init(&als_get_adc_mutex);

	  ret = lightsensor_setup(lpi);
	  if (ret < 0) {
		    pr_err("[ltr558 error]%s: lightsensor_setup error!!\n",__func__);
		    goto err_lightsensor_setup;
	  }

	  ret = psensor_setup(lpi);
	  if (ret < 0) {
		    pr_err("[ltr558 error]%s: psensor_setup error!!\n",__func__);
		    goto err_psensor_setup;
	  }

	  lpi->lp_wq = create_singlethread_workqueue("ltr558_wq");
	  if (!lpi->lp_wq) {
		    pr_err("[ltr558 error]%s: can't create workqueue\n", __func__);
		    ret = -ENOMEM;
		    goto err_create_singlethread_workqueue;
	  }

	  wake_lock_init(&(lpi->ps_wake_lock), WAKE_LOCK_SUSPEND, "proximity");


	 ret = ltr558_setup(lpi);
	 if (ret < 0) {
		   pr_err("[ltr558 error]%s: ltr558_setup error!\n", __func__);
		   goto err_ltr558_setup;
	 }

    lpi->ltr558_class = class_create(THIS_MODULE, "optical_sensors");
    if (IS_ERR(lpi->ltr558_class)) {
        ret = PTR_ERR(lpi->ltr558_class);
        lpi->ltr558_class = NULL;
        goto err_create_class;
    }
    lpi->ls_dev = device_create(lpi->ltr558_class,
                NULL, 0, "%s", "lightsensor");
    if (unlikely(IS_ERR(lpi->ls_dev))) {
        ret = PTR_ERR(lpi->ls_dev);
        lpi->ls_dev = NULL;
        goto err_create_ls_device;
    }

    /* register the attributes */
    ret = device_create_file(lpi->ls_dev, &dev_attr_als_enable);
    if (ret)
        goto err_create_ls_device_file;

    lpi->ps_dev = device_create(lpi->ltr558_class,
                NULL, 0, "%s", "proximity");
    if (unlikely(IS_ERR(lpi->ps_dev))) {
        ret = PTR_ERR(lpi->ps_dev);
        lpi->ps_dev = NULL;
        goto err_create_ps_device;
    }

    /* register the attributes */
    ret = device_create_file(lpi->ps_dev, &dev_attr_ps_enable);
    if (ret)
        goto err_create_ps_device_file1;

    /* register the attributes */

    lpi->early_suspend.level =
			EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	  lpi->early_suspend.suspend = ltr558_early_suspend;
	  lpi->early_suspend.resume = ltr558_late_resume;
	  register_early_suspend(&lpi->early_suspend);

    lpi->als_enable = 1;
    lpi->ps_enable = 1;
    lpi->ps_irq_flag = 0;
    ltr558_devinit();

	  D("[ltr558] %s: Probe success!\n", __func__);
	  printk("[ltr558] Probe and setup success!\n");

	 return ret;

err_create_ps_device_file1:
	  device_unregister(lpi->ps_dev);
err_create_ps_device:
    device_remove_file(lpi->ls_dev, &dev_attr_als_enable);
err_create_ls_device_file:
	  device_unregister(lpi->ls_dev);
err_create_ls_device:
	  class_destroy(lpi->ltr558_class);
err_create_class:
err_ltr558_setup:
	  wake_lock_destroy(&(lpi->ps_wake_lock));
	  destroy_workqueue(lpi->lp_wq);
err_create_singlethread_workqueue:
    free_irq(lpi->irq, lpi);
	  input_unregister_device(lpi->ps_input_dev);
	  input_free_device(lpi->ps_input_dev);
	  misc_deregister(&ltr558_psensor_misc);
err_psensor_setup:
    regulator_disable(lpi->ls_regulator);/*disable power*/
	  input_unregister_device(lpi->ls_input_dev);
	  input_free_device(lpi->ls_input_dev);
	  misc_deregister(&lightsensor_misc);
err_lightsensor_setup:
	  mutex_destroy(&als_enable_mutex);
	  mutex_destroy(&als_disable_mutex);
	  mutex_destroy(&als_get_adc_mutex);
    pdata->exit(NULL); /* free gpio request */
    err_platform_data_null:
	  kfree(lpi);
	  return ret;
}
Beispiel #2
0
static int ltr558_probe(struct i2c_client *client, const struct i2c_device_id *id){
	int ret = 0;
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);

	/* Return 1 if adapter supports everything we need, 0 if not. */
	if (!i2c_check_functionality(adapter, 
		I2C_FUNC_SMBUS_WRITE_BYTE |I2C_FUNC_SMBUS_READ_BYTE_DATA)){
		LTRERR(KERN_ALERT "%s: LTR-558ALS functionality check failed.\n", __func__);
		ret = -EIO;
		goto exit_check_functionality_failed;
	}

	/* data memory allocation */
	ltr558_data = kzalloc(sizeof(struct ltr558_data), GFP_KERNEL);
	if (ltr558_data == NULL) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS kzalloc failed.\n", __func__);
		ret = -ENOMEM;
		goto exit_alloc_data_failed;
	}
	ltr558_data->ltr558_irq = client->irq;
	//printk("%s: Irq number is == %d\n",client->irq);
	
	ltr558_data->p_enable = 0;
	ltr558_data->l_enable = 0;
	ltr558_data->ltr558_input = NULL;
	ltr558_data->client = client;
	INIT_WORK(&(ltr558_data->irq_workqueue),ltr558_schedwork);
	i2c_set_clientdata(client, ltr558_data);
	
	/*init device by send i2c command*/
	ret = ltr558_devinit();
	if (ret) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS device init failed.\n", __func__);
		goto exit_device_init_failed;
	}

	/*init  & register input dev*/
	ltr558_data->ltr558_input = input_allocate_device();
	if (ltr558_data->ltr558_input == NULL) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS cllocate input device fail.\n", __func__);
		ret = -ENOMEM;
		goto exit_input_dev_alloc_failed;
	}
	
	ltr558_data->ltr558_input->name = "lightsensor";
	set_bit(EV_ABS, ltr558_data->ltr558_input->evbit);
	input_set_abs_params(ltr558_data->ltr558_input, ABS_MISC, 0, 100000, 0, 0);
	input_set_abs_params(ltr558_data->ltr558_input, ABS_DISTANCE, 0, 128, 0, 0);	

	ret = input_register_device(ltr558_data->ltr558_input);
	if (ret) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS failed to register input device.\n", __func__);
		goto exit_input_register_device_failed;
	}	

	/*register misc device*/
	ret = misc_register(&ltr558_device);
	if (ret) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS misc_register als failed.\n", __func__);
		goto exit_misc_device_register_failed;
	}

	/*init irq*/
	ret = ltr558_gpio_irq();
	if (ret) {
		LTRERR(KERN_ALERT "%s: LTR-558ALS gpio_irq failed.\n", __func__);
		goto exit_irq_request_failed;
	}

#if 0
//add charles.hu  just for test
	mdelay(600);
	ltr558_als_enable(ALS_RANGE2_64K);
	ltr558_ps_enable(PS_GAINRANGE);
	mdelay(600);
	P_L_printk("Ltr558 probe ok!!!\n");
//add end	
#endif	

	return 0;

exit_irq_request_failed:
	misc_deregister(&ltr558_device);
exit_misc_device_register_failed:
exit_input_register_device_failed:
	input_free_device(ltr558_data->ltr558_input);
exit_input_dev_alloc_failed:
exit_device_init_failed:
	kfree(ltr558_data);
exit_alloc_data_failed:
exit_check_functionality_failed:
	return ret;
}