static int mma8452_input_init(struct gs_mma8452_data *mma) { int err; INIT_WORK(&mma->work,mma8452_work_func); mma->input_dev=input_allocate_device(); if(!mma->input_dev) { err=-ENOMEM; dev_err(&mma->client->dev,"intput device allocate failed\n"); goto err0; } mma->input_dev->open = NULL; mma->input_dev->close = NULL; mma->input_dev->name = ACCL_INPUT_DEV_NAME; //acc->input->name = "accelerometer"; mma->input_dev->id.bustype = BUS_I2C; mma->input_dev->dev.parent = &mma->client->dev; input_set_drvdata(mma->input_dev, mma); mma->input_dev->evbit[0]=BIT_MASK(EV_ABS); input_set_abs_params(mma->input_dev, ABS_X, -8192, 8191, INPUT_FUZZ, INPUT_FLAT); input_set_abs_params(mma->input_dev, ABS_Y, -8192, 8191, INPUT_FUZZ, INPUT_FLAT); input_set_abs_params(mma->input_dev, ABS_Z, -8192, 8191, INPUT_FUZZ, INPUT_FLAT); err = input_register_device(mma->input_dev); if (err) { dev_err(&mma->client->dev, "unable to register input device %s\n", mma->input_dev->name); goto err1; } err = set_sensor_input(ACC, mma->input_dev->dev.kobj.name); if (err) { dev_err(&mma->client->dev, "%s set_sensor_input failed!\n", __func__); goto err1; } hrtimer_init(&mma->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); mma->timer.function = mma8452_timer_func; mma_wq = create_singlethread_workqueue("mma_wq"); if (!mma_wq) return -ENOMEM; dev_info(&mma->client->dev, "mma8452_input_init: init input_dev success! result=%d\n", err); return 0; err1: input_free_device(mma->input_dev); err0: return err; }
static int aps_12d_probe( struct i2c_client *client, const struct i2c_device_id *id) { /* define and initialization the value */ int value_lsb = 0; int value_msb = 0; int ret; struct aps_data *aps; /*the aps_12d sensors ispower on*/ int i; #ifdef CONFIG_ARCH_MSM7X30 struct vreg *vreg_gp4=NULL; int rc; /*delete this line,27A don't have to match the power supply*/ vreg_gp4 = vreg_get(NULL, VREG_GP4_NAME); if (IS_ERR(vreg_gp4)) { pr_err("%s:gp4 power init get failed\n", __func__); } /* set gp4 voltage as 2700mV for all */ rc = vreg_set_level(vreg_gp4,VREG_GP4_VOLTAGE_VALUE_2700); if (rc) { pr_err("%s: vreg_gp4 vreg_set_level failed (%d)\n", __func__, rc); return rc; } rc = vreg_enable(vreg_gp4); if (rc) { pr_err("%s: vreg_gp4 vreg_enable failed (%d)\n", __func__, rc); return rc; } #endif mdelay(5); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk(KERN_ERR "aps_12d_probe: need I2C_FUNC_I2C\n"); ret = -ENODEV; goto err_check_functionality_failed; } /* if querry the board is T1 or T2 turn off the proximity */ /* This modification for version A&B of U8800,only */ if((machine_is_msm7x30_u8800())&&((get_hw_sub_board_id() == HW_VER_SUB_VA) || ((get_hw_sub_board_id() == HW_VER_SUB_VB)))) { printk(KERN_ERR "aps_12d_probe: aps is not supported in U8800 and U8800 T1 board!\n"); ret = -ENODEV; goto err_check_functionality_failed; } aps = kzalloc(sizeof(*aps), GFP_KERNEL); if (aps == NULL) { ret = -ENOMEM; goto err_alloc_data_failed; } mutex_init(&aps->mlock); INIT_WORK(&aps->work, aps_12d_work_func); aps->client = client; i2c_set_clientdata(client, aps); PROXIMITY_DEBUG(KERN_INFO "ghj aps_12d_probe send command 2\n "); /* Command 2 register: 25mA,DC,12bit,Range1 */ /*power_down to avoid the iic read error */ aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); /*init the flag,because everlight's 0x06,0x07's register's value low 4 bit is 0*/ value_lsb = aps_i2c_reg_read(aps, APS_INT_HT_LSB); value_msb = aps_i2c_reg_read(aps, APS_INT_HT_MSB); old_lsb = value_lsb; old_msb = value_msb; /* debug--- stare at the value of lsb & msb */ APS_DBG("value_lsb=%d,value_msb=%d\n",value_lsb,value_msb); /* judge the device type */ /* when 06 07 registers don't equal 0x00, we think it's a intersil hardware */ if((0x00 == value_lsb) && (0x00 == value_msb)) { intersil_flag = EVERLIGHT; } else { intersil_flag = INTERSIL; } /* write reg value for the two device */ if(EVERLIGHT == intersil_flag) { ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_50MA << 6 | \ APS_12D_FREQ_SEL_DC << 4 | \ APS_12D_RES_SEL_12 << 2 | \ APS_12D_RANGE_SEL_ALS_1000)); } else { /*because Power-up and Power Supply Considerations is not good enough for intersil's datasheet,so avoid it via software*/ ret = aps_i2c_reg_write(aps, APS_TEST, APS_12D_POWER_DOWN); if (ret < 0) { PROXIMITY_DEBUG("APS_TEST error!\n"); } msleep(10); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD1, APS_12D_POWER_DOWN); if (ret < 0) { PROXIMITY_DEBUG("APS_12D_POWER_DOWN error!\n"); } msleep(10); ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \ (uint8_t)(APS_12D_IRDR_SEL_INTERSIL_50MA << 4 | \ APS_FREQ_INTERSIL_DC << 6 | \ APS_ADC_12 << 2 | \ APS_INTERSIL_SCHEME_OFF| \ APS_12D_RANGE_SEL_ALS_1000)); } err_threshold_value[1] = 50; if (ret < 0) { goto err_detect_failed; } range_index = 0; #ifdef CONFIG_HUAWEI_HW_DEV_DCT /* detect current device successful, set the flag as present */ set_hw_dev_flag(DEV_I2C_APS); #endif for(i = 0; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do NOT use the last one */ /* get the down_range_value */ if(EVERLIGHT == intersil_flag) { up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value_U8661[i] - RANGE_FIX + 500; } else { up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value_U8661_I[i] - RANGE_FIX + 500; } } down_range_value[0] = 0; for(i = 1; i < TOTAL_RANGE_NUM; i++) { /* NOTE: do not use the first one */ /* get the down_range_value */ if(EVERLIGHT == intersil_flag) { down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value_U8661[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4 - 650; } else { down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value_U8661_I[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4 - 650; } } /*we don't use the input device sensors again */ aps->input_dev = input_allocate_device(); if (aps->input_dev == NULL) { ret = -ENOMEM; PROXIMITY_DEBUG(KERN_ERR "aps_12d_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } aps->input_dev->name = "sensors_aps"; aps->input_dev->id.bustype = BUS_I2C; input_set_drvdata(aps->input_dev, aps); ret = input_register_device(aps->input_dev); if (ret) { printk(KERN_ERR "aps_probe: Unable to register %s input device\n", aps->input_dev->name); goto err_input_register_device_failed; } set_bit(EV_ABS, aps->input_dev->evbit); input_set_abs_params(aps->input_dev, ABS_LIGHT, 0, 10240, 0, 0); input_set_abs_params(aps->input_dev, ABS_DISTANCE, 0, 1, 0, 0); ret = misc_register(&light_device); if (ret) { printk(KERN_ERR "aps_12d_probe: light_device register failed\n"); goto err_light_misc_device_register_failed; } ret = misc_register(&proximity_device); if (ret) { printk(KERN_ERR "aps_12d_probe: proximity_device register failed\n"); goto err_proximity_misc_device_register_failed; } if( light_device.minor != MISC_DYNAMIC_MINOR ){ light_device_minor = light_device.minor; } if( proximity_device.minor != MISC_DYNAMIC_MINOR ){ proximity_device_minor = proximity_device.minor ; } wake_lock_init(&proximity_wake_lock, WAKE_LOCK_SUSPEND, "proximity"); hrtimer_init(&aps->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); aps->timer.function = aps_timer_func; aps_wq = create_singlethread_workqueue("aps_wq"); if (!aps_wq) { ret = -ENOMEM; goto err_create_workqueue_failed; } this_aps_data =aps; ret = set_sensor_input(PS, aps->input_dev->dev.kobj.name); if (ret) { dev_err(&client->dev, "%s set_sensor_input failed\n", __func__); goto err_create_workqueue_failed; } ret = set_sensor_input(ALS, aps->input_dev->dev.kobj.name); if (ret) { dev_err(&client->dev, "%s set_sensor_input failed\n", __func__); goto err_create_workqueue_failed; } /* delete the redundant code */ printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n"); set_sensors_list(L_SENSOR + P_SENSOR); return 0; err_create_workqueue_failed: misc_deregister(&proximity_device); err_proximity_misc_device_register_failed: misc_deregister(&light_device); err_light_misc_device_register_failed: err_input_register_device_failed: input_free_device(aps->input_dev); err_input_dev_alloc_failed: err_detect_failed: kfree(aps); err_alloc_data_failed: err_check_functionality_failed: #ifdef CONFIG_ARCH_MSM7X30 if(NULL != vreg_gp4) { /* can't use the flag ret here, it will change the return value of probe function */ vreg_disable(vreg_gp4); /* delete a line */ } #endif return ret; }
static int __devinit adxl34x_initialize(bus_device *bus, struct adxl34x *ac) { struct input_dev *input_dev; struct adxl34x_platform_data *devpd = bus->dev.platform_data; struct adxl34x_platform_data *pdata; int err, range; unsigned char revid; if (!bus->irq) { dev_err(&bus->dev, "no IRQ?\n"); return -ENODEV; } if (NULL == devpd) { dev_err(&bus->dev, "No platfrom data: Using default initialization\n"); return -ENOMEM; } memcpy(&ac->pdata, devpd, sizeof(ac->pdata)); pdata = &ac->pdata; input_dev = input_allocate_device(); if (!input_dev) { dev_err(&bus->dev, "%s: input device allocation failed\n", __func__); return -ENOMEM; } ac->input = input_dev; ac->disabled = 1; INIT_WORK(&ac->work, adxl34x_work); mutex_init(&ac->mutex); revid = ac->read(bus, DEVID); switch (revid) { case ID_ADXL345: ac->model = ACC_ADXL345; break; case ID_ADXL346: ac->model = ACC_ADXL346; break; default: dev_err(&bus->dev, "Read ACC ADXL Chip ID Err 0x%x\n", revid); err = -ENODEV; goto err_free_mem; } dev_info(&bus->dev, "Read ACC ADXL OK ,Chip ID is 0x%x\n", revid); snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(&bus->dev)); input_dev->name = ACCL_INPUT_DEV_NAME; input_dev->phys = ac->phys; input_dev->dev.parent = &bus->dev; input_dev->id.product = ac->model; input_dev->id.bustype = BUS_I2C; /*input_dev->open = adxl34x_input_open;*/ /*input_dev->close = adxl34x_input_close;*/ input_dev->open = NULL; input_dev->close = NULL; input_set_drvdata(input_dev, ac); __set_bit(ac->pdata.ev_type, input_dev->evbit); if (ac->pdata.ev_type == EV_REL) { __set_bit(REL_X, input_dev->relbit); __set_bit(REL_Y, input_dev->relbit); __set_bit(REL_Z, input_dev->relbit); } else { /* EV_ABS */ __set_bit(ABS_X, input_dev->absbit); __set_bit(ABS_Y, input_dev->absbit); __set_bit(ABS_Z, input_dev->absbit); if (pdata->data_range & FULL_RES) range = ADXL_FULLRES_MAX_VAL; /* Signed 13-bit */ else range = ADXL_FIXEDRES_MAX_VAL; /* Signed 10-bit */ input_set_abs_params(input_dev, ABS_X, -range, range, 3, 3); input_set_abs_params(input_dev, ABS_Y, -range, range, 3, 3); input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3); } __set_bit(EV_KEY, input_dev->evbit); __set_bit(pdata->ev_code_tap_x, input_dev->keybit); __set_bit(pdata->ev_code_tap_y, input_dev->keybit); __set_bit(pdata->ev_code_tap_z, input_dev->keybit); if (pdata->ev_code_ff) { ac->int_mask = FREE_FALL; __set_bit(pdata->ev_code_ff, input_dev->keybit); } if (pdata->ev_code_act_inactivity) __set_bit(pdata->ev_code_act_inactivity, input_dev->keybit); ac->int_mask |= ACTIVITY | INACTIVITY; if (pdata->watermark) { ac->int_mask |= WATERMARK; if (!FIFO_MODE(pdata->fifo_mode)) pdata->fifo_mode |= FIFO_STREAM; } else { ac->int_mask |= DATA_READY; } if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN)) ac->int_mask |= SINGLE_TAP | DOUBLE_TAP; if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) ac->fifo_delay = 0; ac->write(bus, POWER_CTL, 0); err = adxl34x_config_gpio(&bus->dev, ac); if (err < 0) { dev_err(&bus->dev, "%s: failed to config gpio lowpower mode\n", __func__); goto err_clear_inputdev; } if (bus->irq >= 0) { err = gpio_request(irq_to_gpio(bus->irq), "gsensor_gpio"); if (err) { dev_err(&bus->dev, "%s: failed to request gpio for irq\n", __func__); goto err_clear_inputdev; } gpio_direction_input(bus->irq); } err = sysfs_create_group(&bus->dev.kobj, &adxl34x_attr_group); if (err) { dev_err(&bus->dev, "ADXL34X register sysfs failed\n"); goto err_free_gpio; } err = input_register_device(input_dev); if (err) { dev_err(&bus->dev, "ADXL34X register input device failed\n"); goto err_remove_attr; } AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); AC_WRITE(ac, OFSX, pdata->x_axis_offset); ac->hwcal.x = pdata->x_axis_offset; AC_WRITE(ac, OFSY, pdata->y_axis_offset); ac->hwcal.y = pdata->y_axis_offset; AC_WRITE(ac, OFSZ, pdata->z_axis_offset); ac->hwcal.z = pdata->z_axis_offset; AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); AC_WRITE(ac, DUR, pdata->tap_duration); AC_WRITE(ac, LATENT, pdata->tap_latency); AC_WRITE(ac, WINDOW, pdata->tap_window); AC_WRITE(ac, THRESH_ACT, pdata->activity_threshold); AC_WRITE(ac, THRESH_INACT, pdata->inactivity_threshold); AC_WRITE(ac, TIME_INACT, pdata->inactivity_time); AC_WRITE(ac, THRESH_FF, pdata->free_fall_threshold); AC_WRITE(ac, TIME_FF, pdata->free_fall_time); AC_WRITE(ac, TAP_AXES, pdata->tap_axis_control); AC_WRITE(ac, ACT_INACT_CTL, pdata->act_axis_control); AC_WRITE(ac, BW_RATE, RATE(ac->pdata.data_rate) | (pdata->low_power_mode ? LOW_POWER : 0)); AC_WRITE(ac, DATA_FORMAT, pdata->data_range); AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) | SAMPLES(pdata->watermark)); AC_WRITE(ac, INT_MAP, 0); /* Map all INTs to INT1 */ AC_WRITE(ac, INT_ENABLE, 0); /* pdata->power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK); */ pdata->power_mode &= PCTL_LINK; if (bus->irq >= 0) { err = request_irq(bus->irq, adxl34x_irq, IRQF_TRIGGER_HIGH, bus->dev.driver->name, ac); if (err) { dev_err(&bus->dev, "irq %d busy?\n", bus->irq); goto err_unreg_inputdev; } } #ifdef CONFIG_HUAWEI_SENSORS_INPUT_INFO err = set_sensor_input(ACC, input_dev->dev.kobj.name); if (err) { if (bus->irq >= 0) { free_irq(ac->bus->irq, ac); } dev_err(&bus->dev, "%s set_sensor_input failed\n", __func__); goto err_unreg_inputdev; } #endif dev_dbg(&bus->dev, "ADXL%d accelerometer, irq %d\n", ac->model, bus->irq); return 0; err_unreg_inputdev: input_unregister_device(input_dev); err_remove_attr: sysfs_remove_group(&bus->dev.kobj, &adxl34x_attr_group); err_free_gpio: if (bus->irq >= 0) gpio_free(irq_to_gpio(bus->irq)); err_clear_inputdev: input_set_drvdata(input_dev, NULL); err_free_mem: input_free_device(input_dev); return err; }
static int l3g4200d_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct l3g4200d_data *data; struct gyro_platform_data *platform_data = NULL; int ret = -1; int tempvalue; GYRO_DBG("l3g4200d_probe start!\n"); if (client->dev.platform_data == NULL) { dev_err(&client->dev, "platform data is NULL. exiting.\n"); ret = -ENODEV; goto exit; } /*gyro mate power*/ platform_data = client->dev.platform_data; if(platform_data->gyro_power) { ret = platform_data->gyro_power(IC_PM_ON); if( ret < 0) { dev_err(&client->dev, "gyro power on error!\n"); goto exit; } } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { ret = -ENODEV; goto exit_pm_off; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)){ ret = -ENODEV; goto exit_pm_off; } /* * OK. For now, we presume we have a valid client. We now create the * client structure, even though we cannot fill it completely yet. */ data = kzalloc(sizeof(struct l3g4200d_data), GFP_KERNEL); if (NULL == data) { dev_err(&client->dev, "failed to allocate memory for module data\n"); ret = -ENOMEM; goto exit_pm_off; } mutex_init(&data->mlock); INIT_WORK(&data->work, gy_work_func); i2c_set_clientdata(client, data); data->client = client; data->pdata = platform_data; ret = l3g4200d_validate_pdata(data); if (ret < 0) { dev_err(&client->dev, "failed to validate platform data\n"); goto exit_kfree; } ret = i2c_smbus_read_byte(client); if ( ret < 0) { GYRO_DBG("i2c_smbus_read_byte error!!\n"); goto err_detect_failed; } else { GYRO_DBG("L3G4200D Device detected!\n"); } /* read chip id */ tempvalue = i2c_smbus_read_word_data(client, WHO_AM_I); if ((tempvalue & 0x00FF) == 0x00D3) { GYRO_DBG("I2C driver registered!\n"); } else { data->client = NULL; ret = -ENODEV; goto err_detect_failed; } if (sensor_dev == NULL) { data->input_dev = input_allocate_device(); if (data->input_dev == NULL) { ret = -ENOMEM; printk(KERN_ERR "gs_probe: Failed to allocate input device\n"); goto err_input_dev_alloc_failed; } data->input_dev->name = "gy_sensors"; sensor_dev = data->input_dev; }else{ data->input_dev = sensor_dev; } data->input_dev->id.vendor = VENDOR; #if 0 set_bit(EV_REL,data->input_dev->evbit); set_bit(REL_RX, data->input_dev->absbit); set_bit(REL_RY, data->input_dev->absbit); set_bit(REL_RZ, data->input_dev->absbit); #endif set_bit(EV_ABS,data->input_dev->evbit); /* modify the func of init */ input_set_abs_params(data->input_dev, ABS_RX, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_RY, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_RZ, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_X, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_Y, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_Z, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_THROTTLE, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_RUDDER, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_WHEEL, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_GAS, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_HAT0X, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_HAT0Y, MIN_VALUE, MAX_VALUE, 0, 0); input_set_abs_params(data->input_dev, ABS_BRAKE, MIN_VALUE, MAX_VALUE, 0, 0); set_bit(EV_SYN,data->input_dev->evbit); data->input_dev->id.bustype = BUS_I2C; input_set_drvdata(data->input_dev, data); ret = input_register_device(data->input_dev); if (ret) { printk(KERN_ERR "gy_probe: Unable to register %s input device\n", data->input_dev->name); /* create l3g-dev device class */ goto err_input_register_device_failed; } ret = misc_register(&gysensor_device); if (ret) { printk(KERN_ERR "gy_probe: gysensor_device register failed\n"); goto err_misc_device_register_failed; } hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->timer.function = gy_timer_func; atomic_set(&a_flag, 0); data->flags = -1; #ifdef CONFIG_HAS_EARLYSUSPEND data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = gy_early_suspend; data->early_suspend.resume = gy_late_resume; register_early_suspend(&data->early_suspend); #endif GYRO_DBG("L3G4200D device created successfully\n"); gy_wq = create_singlethread_workqueue("gy_wq"); /* log for create workqueue fail */ if (!gy_wq) { ret = -ENOMEM; printk(KERN_ERR "%s, line %d: create_singlethread_workqueue fail!\n", __func__, __LINE__); goto err_gy_create_workqueue_failed; } gyro = data; // hrtimer_start(&this_gs_data->timer, ktime_set(0, 500000000), HRTIMER_MODE_REL); #ifdef CONFIG_HUAWEI_HW_DEV_DCT /* detect current device successful, set the flag as present */ set_hw_dev_flag(DEV_I2C_GYROSCOPE); #endif ret = set_sensor_input(GYRO, data->input_dev->dev.kobj.name); if (ret) { dev_err(&client->dev, "%s set_sensor_input failed\n", __func__); goto err_misc_device_register_failed; } printk(KERN_DEBUG "l3g4200d_probe successful"); set_sensors_list(GY_SENSOR); return 0; /*add gyro exception process*/ err_gy_create_workqueue_failed: #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&data->early_suspend); #endif hrtimer_cancel(&data->timer); err_misc_device_register_failed: misc_deregister(&gysensor_device); err_input_register_device_failed: input_free_device(gyro->input_dev); err_input_dev_alloc_failed: err_detect_failed: exit_kfree: kfree(gyro); exit_pm_off: /*No need to power down*/ exit: return ret; }
static int __init po188_init(void) { int err = -1; int ret = -1; struct kobject *kobj = NULL; struct regulator* ldo15_3v3; po188_driver.dev.name = PO188_DEV_NAME; po188_driver.dev.minor = MISC_DYNAMIC_MINOR; po188_driver.fops.unlocked_ioctl = po188_ioctl; po188_driver.dev.fops = &po188_driver.fops; po188_driver.last_voltage = 0; //set the initial delay value: 1s po188_driver.delay_time = SENSOR_POLLING_JIFFIES; // mutex_init(&po188_driver.lock); if ((err = misc_register(&po188_driver.dev))) { PO188_ERRMSG("misc_register failed"); goto misc_register_failed; } //regulater config ldo15_3v3 = regulator_get(po188_driver.dev.this_device, "light-vcc"); if (IS_ERR(ldo15_3v3)) { PO188_ERRMSG("cannot get po188 vcc drive"); goto regulator_get_failed; } gPo188Regulator = ldo15_3v3; ret = regulator_set_voltage(ldo15_3v3, PO188_VCC_VOLTAGE, PO188_VCC_VOLTAGE); if (ret < 0) { PO188_ERRMSG("set po188 vcc drive error"); goto regulator_set_voltage_failed; } /* ret = regulator_enable(ldo15_3v3); if (ret < 0) { PO188_ERRMSG("enable po188 vcc drive error"); goto regulator_enable_failed; }*/ po188_driver.po188_wq = create_singlethread_workqueue("po188_wq"); if (!po188_driver.po188_wq) { PO188_ERRMSG("create workque failed \n"); goto create_singlethread_workqueue_failed; } //set time, and time overrun function init_timer(&po188_driver.timer); po188_driver.timer.expires = jiffies + msecs_to_jiffies( po188_driver.delay_time); po188_driver.timer.data = 0; po188_driver.timer.function = po188_start_cb_thread; //add_timer(&po188_driver.timer); po188_driver.input_dev = input_allocate_device(); if (po188_driver.input_dev == NULL) { PO188_ERRMSG("po188_init : Failed to allocate input device\n"); goto input_allocate_device_failed; } po188_driver.input_dev->name = PO188_DEV_NAME; input_set_drvdata(po188_driver.input_dev, &po188_driver); ret = input_register_device(po188_driver.input_dev); if (ret) { PO188_ERRMSG("Unable to register %s input device\n", po188_driver.input_dev->name); goto input_register_device_failed; } err = set_sensor_input(PO188, po188_driver.input_dev->dev.kobj.name); if (err) { PO188_ERRMSG("set_sensor_input error\n"); goto set_sensor_input_failed; } set_bit(EV_ABS,po188_driver.input_dev->evbit); set_bit(EV_SYN,po188_driver.input_dev->evbit); input_set_abs_params(po188_driver.input_dev, ABS_MISC, 0, 10000, 0, 0); /*no need early_suspend, the system can call enable/disable when suspend and resume*/ /* po188_driver.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; po188_driver.early_suspend.suspend = Po188_suspend; po188_driver.early_suspend.resume = Po188_resume; register_early_suspend(&po188_driver.early_suspend);*/ kobj = kobject_create_and_add(PO188_NAME, NULL); if (kobj == NULL) { goto kobject_create_and_add_failed; } if (sysfs_create_group(kobj, &po188_defattr_group)) { goto sysfs_create_group_failed; } spin_lock_init(&po188_driver.s_lock); po188_driver.status_on = false; //status_on must have init value /* //open adc channel ret = k3_adc_open_channel(PO188_ADC_CHANNEL); if (ret < 0) { PO188_ERRMSG("k3_adc_open_channel error\n"); goto k3_adc_open_channel_failed; }*/ return 0; //k3_adc_open_channel_failed: // sysfs_remove_group(&po188_driver.dev.parent->kobj, &po188_defattr_group); sysfs_create_group_failed: kobject_put(kobj); kobject_create_and_add_failed: set_sensor_input_failed: input_unregister_device(po188_driver.input_dev); input_register_device_failed: input_free_device(po188_driver.input_dev); input_allocate_device_failed: destroy_workqueue(po188_driver.po188_wq); create_singlethread_workqueue_failed: // regulator_disable(ldo15_3v3); //regulator_enable_failed: regulator_set_voltage_failed: regulator_put(ldo15_3v3); regulator_get_failed: misc_deregister(&po188_driver.dev); misc_register_failed: return err; }