Exemplo n.º 1
0
static int gs_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{	
      int ret;
      struct gs_data *gs;
     	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_ERR "gs_probe: need I2C_FUNC_I2C\n");
		ret = -ENODEV;
		goto err_check_functionality_failed;
	}
#ifndef GS_POLLING
	ret = gs_config_int1_pin();
	if(ret <0)
	{
		goto err_check_functionality_failed;
	}
	
	ret = gs_config_int2_pin();
	if(ret <0)
	{
		goto err_check_functionality_failed;
	}	
#endif
	gs = kzalloc(sizeof(*gs), GFP_KERNEL);
	if (gs == NULL) {		
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	
		mutex_init(&gs->mlock);
	
	INIT_WORK(&gs->work, gs_work_func);
	gs->client = client;
	i2c_set_clientdata(client, gs);
	
	
	 ret =reg_read(gs,GS_ADI_REG_DEVID);		
	if ( ret <0 )
		goto err_detect_failed;
	 
	 ret = reg_write(gs,GS_ADI_REG_POWER_CTL,0x14);   /* auto low power ,deep sleep */
	if ( ret <0 )
		goto err_detect_failed;
	ret =  reg_write(gs,GS_ADI_REG_BW,0x0a);    /* Rate: 100Hz, IDD: 130uA */
      if ( ret <0 )
		goto err_detect_failed;
	 ret = reg_write(gs,GS_ADI_REG_DATA_FORMAT,0x01);  /* Data Format: 8g right justified  	128=1g  8g*/
	 if ( ret <0 )
			 goto err_detect_failed;

	 ret = reg_write(gs,GS_ADI_REG_INT_ENABLE,0x80); /* enable  int Int En: Data Rdy*/

	 if ( ret <0 )
			 goto err_detect_failed;

	 ret = reg_write(gs,GS_ADI_REG_TAP_AXES,0x01);	/* Z Axis Tap */
	 if ( ret <0 )
		goto err_detect_failed;
       ret = reg_write(gs,GS_ADI_REG_THRESH_TAP,0x20);	/* Tap Threshold: 2G */
	   if ( ret <0 )
			   goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_DUR,0x50);	/* Dur:50ms */
	 if ( ret <0 )
			 goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_LATENT,0x20);	 /* Latent: 40ms */
	 if ( ret <0 )
			 goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_WINDOW,0xF0);	 /* Window: 300ms */
	 if ( ret <0 )
			 goto err_detect_failed;
	 
	if (sensor_dev == NULL)
	{
		gs->input_dev = input_allocate_device();
		if (gs->input_dev == NULL) {
			ret = -ENOMEM;
			printk(KERN_ERR "gs_probe: Failed to allocate input device\n");
			goto err_input_dev_alloc_failed;
		}
		gs->input_dev->name = "sensors";
		sensor_dev = gs->input_dev;
	}else{
	
		gs->input_dev = sensor_dev;
	}
	gs->input_dev->id.vendor = GS_ADIX345;//for akm8973 compass detect.

	set_bit(EV_ABS,gs->input_dev->evbit);
	
	set_bit(ABS_X, gs->input_dev->absbit);
	set_bit(ABS_Y, gs->input_dev->absbit);
	set_bit(ABS_Z, gs->input_dev->absbit);
	
	set_bit(EV_SYN,gs->input_dev->evbit);


	gs->input_dev->id.bustype = BUS_I2C;
	//gs->input_dev->open = gs_adi_input_open;
	//gs->input_dev->close = gs_adi_input_close;
	
	input_set_drvdata(gs->input_dev, gs);
	ret = input_register_device(gs->input_dev);
	if (ret) {
		printk(KERN_ERR "gs_probe: Unable to register %s input device\n", gs->input_dev->name);
		goto err_input_register_device_failed;
	}
	
	ret = misc_register(&gsensor_device);
	if (ret) {

		printk(KERN_ERR "gs_probe: gsensor_device register failed\n");

		goto err_misc_device_register_failed;
	}

	
#ifndef   GS_POLLING 
	if (client->irq) {
		ret = request_irq(client->irq, gs_irq_handler, 0, client->name, gs);
		
		if (ret == 0)
			gs->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}
#endif 



	if (!gs->use_irq) {
		hrtimer_init(&gs->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		gs->timer.function = gs_timer_func;
		
	}
#ifdef CONFIG_HAS_EARLYSUSPEND
	gs->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	gs->early_suspend.suspend = gs_early_suspend;
	gs->early_suspend.resume = gs_late_resume;
	register_early_suspend(&gs->early_suspend);
#endif
	
	gs_wq = create_singlethread_workqueue("gs_wq");
	if (!gs_wq)
		return -ENOMEM;
	
#if 0
	else
		GS_SENSOR_ADI_FLAG =1;
#endif
      this_gs_data =gs;

	printk(KERN_INFO "gs_probe: Start gs_adixl345  in %s mode\n", gs->use_irq ? "interrupt" : "polling");

	return 0;
	
err_misc_device_register_failed:
	
	misc_deregister(&gsensor_device);

err_input_register_device_failed:
	input_free_device(gs->input_dev);

err_input_dev_alloc_failed:


err_detect_failed:

	kfree(gs);
	
#ifndef   GS_POLLING 
	gs_free_int1();
	gs_free_int2();
#endif	
	
err_alloc_data_failed:
err_check_functionality_failed:
	return ret;
}
static int gs_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{	
   int ret;
   struct gs_data *gs;

	struct vreg *vreg_gp4=NULL;
	int rc;

	vreg_gp4 = vreg_get(NULL, "gp4");
    /* set gp4 voltage as 2700mV for all */
    rc = vreg_set_level(vreg_gp4,VREG_GP4_VOLTAGE_VALUE_2700);
	if (rc) {
		printk("%s: vreg_gp4  vreg_set_level failed \n", __func__);
		return rc;
	}
	
	rc = vreg_enable(vreg_gp4);
	if (rc) {
		printk("%s: vreg_gp4    vreg_enable failed \n", __func__);
		return rc;
	}
	mdelay(5);
   	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		printk(KERN_ERR "gs_probe: need I2C_FUNC_I2C\n");
		ret = -ENODEV;
		goto err_check_functionality_failed;
	}
#ifndef GS_POLLING
	ret = gs_config_int1_pin();
	if(ret <0)
	{
		goto err_check_functionality_failed;
	}
	
	ret = gs_config_int2_pin();
	if(ret <0)
	{
		goto err_check_functionality_failed;
	}	
#endif
	gs = kzalloc(sizeof(*gs), GFP_KERNEL);
	if (gs == NULL) {		
		ret = -ENOMEM;
		goto err_alloc_data_failed;
	}
	
/*BK4D00238, add  mlock, dingxifeng KF14049, 2009-4-3 begin */	
		mutex_init(&gs->mlock);
/*BK4D00238, add  mlock, dingxifeng KF14049, 2009-4-3 end */
	
	INIT_WORK(&gs->work, gs_work_func);
	gs->client = client;
	i2c_set_clientdata(client, gs);
/*BK4D00238, add accelerometer code, dingxifeng KF14049, 2009-5-9 begin */
	
	
	 ret =reg_read(gs,GS_ADI_REG_DEVID);		
	if ( ret <0 )
		goto err_detect_failed;
	switch (ret) {
	case ID_ADXL345:
		break;
	default:
		printk(KERN_ERR, "Failed to probe \n" );
		goto err_detect_failed;
	}
	 
/*BK4D01637, gs_probe interface set standby mode , dingxifeng KF14049, 2009-6-22  begin*/
	 ret = reg_write(gs,GS_ADI_REG_POWER_CTL,0x14);   /* auto low power ,deep sleep */
/*BK4D01637, gs_probe interface set standby mode , dingxifeng KF14049, 2009-6-22  end*/
	if ( ret <0 )
		goto err_detect_failed;
	ret =  reg_write(gs,GS_ADI_REG_BW,0x0a);    /* Rate: 100Hz, IDD: 130uA */
      if ( ret <0 )
		goto err_detect_failed;
	 ret = reg_write(gs,GS_ADI_REG_DATA_FORMAT,0x01);  /* Data Format: 8g right justified  	128=1g  8g*/
	 if ( ret <0 )
			 goto err_detect_failed;

	 ret = reg_write(gs,GS_ADI_REG_INT_ENABLE,0x80); /* enable  int Int En: Data Rdy*/

	 if ( ret <0 )
			 goto err_detect_failed;

	 ret = reg_write(gs,GS_ADI_REG_TAP_AXES,0x01);	/* Z Axis Tap */
	 if ( ret <0 )
		goto err_detect_failed;
       ret = reg_write(gs,GS_ADI_REG_THRESH_TAP,0x20);	/* Tap Threshold: 2G */
	   if ( ret <0 )
			   goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_DUR,0x50);	/* Dur:50ms */
	 if ( ret <0 )
			 goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_LATENT,0x20);	 /* Latent: 40ms */
	 if ( ret <0 )
			 goto err_detect_failed;


	 ret = reg_write(gs,GS_ADI_REG_WINDOW,0xF0);	 /* Window: 300ms */
	 if ( ret <0 )
			 goto err_detect_failed;
	 
	if (sensor_dev == NULL)
	{
		gs->input_dev = input_allocate_device();
		if (gs->input_dev == NULL) {
			ret = -ENOMEM;
			printk(KERN_ERR "gs_probe: Failed to allocate input device\n");
			goto err_input_dev_alloc_failed;
		}
		gs->input_dev->name = "sensors";
		sensor_dev = gs->input_dev;
	}else{
	
		gs->input_dev = sensor_dev;
	}
	gs->input_dev->id.vendor = GS_ADIX345;//for akm8973 compass detect.

	set_bit(EV_ABS,gs->input_dev->evbit);
	
	/* modify for ES-version*/
	input_set_abs_params(gs->input_dev, ABS_X, -11520, 11520, 0, 0);
	input_set_abs_params(gs->input_dev, ABS_Y, -11520, 11520, 0, 0);
	input_set_abs_params(gs->input_dev, ABS_Z, -11520, 11520, 0, 0);
	
	set_bit(EV_SYN,gs->input_dev->evbit);


	gs->input_dev->id.bustype = BUS_I2C;
	//gs->input_dev->open = gs_adi_input_open;
	//gs->input_dev->close = gs_adi_input_close;
	
	input_set_drvdata(gs->input_dev, gs);
	ret = input_register_device(gs->input_dev);
	if (ret) {
		printk(KERN_ERR "gs_probe: Unable to register %s input device\n", gs->input_dev->name);
		goto err_input_register_device_failed;
	}
	
	ret = misc_register(&gsensor_device);
	if (ret) {
/*BK4D02639, modify printk mesg, dingxifeng KF14049, 2009-7-13 begin */

		printk(KERN_ERR "gs_probe: gsensor_device register failed\n");
/*BK4D02639, modify printk mesg, dingxifeng KF14049, 2009-7-13 end */

		goto err_misc_device_register_failed;
	}
/*BK4D00263, add for input devices, dingxifeng KF14049, 2009-5-20 end*/

	
#ifndef   GS_POLLING 
	if (client->irq) {
		ret = request_irq(client->irq, gs_irq_handler, 0, client->name, gs);
		
		if (ret == 0)
			gs->use_irq = 1;
		else
			dev_err(&client->dev, "request_irq failed\n");
	}
#endif 


/*BK4D00238, add accelerometer code, dingxifeng KF14049, 2009-5-9 end */

	if (!gs->use_irq) {
		hrtimer_init(&gs->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		gs->timer.function = gs_timer_func;
		
	}
#ifdef CONFIG_HAS_EARLYSUSPEND
	gs->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	gs->early_suspend.suspend = gs_early_suspend;
	gs->early_suspend.resume = gs_late_resume;
	register_early_suspend(&gs->early_suspend);
#endif
	
	gs_wq = create_singlethread_workqueue("gs_wq");
	if (!gs_wq)
		return -ENOMEM;
	
/*BK4D00263, add for misc devices, dingxifeng KF14049, 2009-5-20begin */
#if 0
	else
		GS_SENSOR_ADI_FLAG =1;
#endif
      this_gs_data =gs;
/*BK4D00263, add for misc devices, dingxifeng KF14049, 2009-5-20 end */

	printk(KERN_INFO "gs_probe: Start gs_adixl345  in %s mode\n", gs->use_irq ? "interrupt" : "polling");

	return 0;
	
/*BK4D00263, add for misc devices, dingxifeng KF14049, 2009-5-20 begin */
err_misc_device_register_failed:
	
	misc_deregister(&gsensor_device);

err_input_register_device_failed:
	input_free_device(gs->input_dev);

err_input_dev_alloc_failed:

/*BK4D00263, add for misc devices, dingxifeng KF14049, 2009-5-20 end */

err_detect_failed:

	kfree(gs);
	
#ifndef   GS_POLLING 
	gs_free_int1();
	gs_free_int2();
#endif	
	
err_alloc_data_failed:
err_check_functionality_failed:
	if (vreg_gp4!=NULL)
	{
		rc = vreg_disable(vreg_gp4);
		if (rc) {
			printk("%s: vreg_gp4    vreg_enable failed \n", __func__);
			return rc;
		}
	}
	return ret;
}