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; }