Пример #1
0
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;
  
}
Пример #3
0
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;
}
Пример #5
0
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;
}