Example #1
0
static int tps61310_probe(struct i2c_client *client,
			       const struct i2c_device_id *devid)
{
	int ret = -1;
	int tempvalue = 0;
	
	printk("tps61310_probe start!\n");

	tps61310_client = client;
	/* GPIO 27 used by BT of some products, we use GPIO 83 instead. */
	if(HW_BT_WAKEUP_GPIO_IS_27 == get_hw_bt_wakeup_gpio_type())
	{
		tps61310_nreset = 83;
	}
	else
	{
		tps61310_nreset = 27;
	}
	/*device init of gpio init*/
	if ( tps61310_device_init()){
		printk("tps61310_device_init error!\n");	
	}
	
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		ret = -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)){
		ret = -ENODEV;
	}
	
	/* read chip id */
	tempvalue = tps61310_i2c_read(tps61310_client, 0x07);
	if ((tempvalue & 0x07) == 0x06) {
		printk("tps61310 read chip id ok!\n");
	} else {
		printk("tps61310 read chip id error!\n");
		return -ENODEV;
	}

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	/* detect current device successful, set the flag as present */
	set_hw_dev_flag(DEV_I2C_FLASH);
#endif

	printk("tps61310_probe end!\n");
	return 0;
}
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;
	}
    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");
	if (!gy_wq)
		return -ENOMEM;

	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
	printk(KERN_DEBUG "l3g4200d_probe   successful");

	return 0;
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:
	if(platform_data->gyro_power)
	{
		platform_data->gyro_power(IC_PM_OFF);
	}
exit:
	return ret;
}
Example #3
0
int32_t hisi_pmic_i2c_probe(struct i2c_client *client,
                            const struct i2c_device_id *id)
{
    struct i2c_adapter *adapter;
    struct hisi_pmic_ctrl_t *pmic_ctrl;
    int32_t rc=0;

    cam_info("%s client name = %s.\n", __func__, client->name);

    adapter = client->adapter;
    if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
        cam_err("%s i2c_check_functionality failed.\n", __func__);
        return -EIO;
    }

    pmic_ctrl = (struct hisi_pmic_ctrl_t *)id->driver_data;
    pmic_ctrl->pmic_i2c_client->client = client;
    pmic_ctrl->dev = &client->dev;
    pmic_ctrl->pmic_i2c_client->i2c_func_tbl = &hisi_pmic_i2c_func_tbl;

    rc = hisi_pmic_get_dt_data(pmic_ctrl);
    if (rc < 0) {
        cam_err("%s hisi_pmic_get_dt_data failed.", __func__);
        return -EFAULT;
    }

    rc = pmic_ctrl->func_tbl->pmic_get_dt_data(pmic_ctrl);
    if (rc < 0) {
        cam_err("%s flash_get_dt_data failed.", __func__);
        return -EFAULT;
    }

    rc = pmic_ctrl->func_tbl->pmic_init(pmic_ctrl);
    if (rc < 0) {
        cam_err("%s pmic init failed.\n", __func__);
        return -EFAULT;
    }

    rc = pmic_ctrl->func_tbl->pmic_match(pmic_ctrl);
    if (rc < 0) {
        cam_err("%s pmic match failed.\n", __func__);
        return -EFAULT;
    }

    if (!pmic_ctrl->pmic_v4l2_subdev_ops)
        pmic_ctrl->pmic_v4l2_subdev_ops = &hisi_pmic_subdev_ops;

    v4l2_subdev_init(&pmic_ctrl->subdev,
                     pmic_ctrl->pmic_v4l2_subdev_ops);

    snprintf(pmic_ctrl->subdev.name,
             sizeof(pmic_ctrl->subdev.name), "%s",
             pmic_ctrl->pmic_info.name);

    v4l2_set_subdevdata(&pmic_ctrl->subdev, client);

    pmic_ctrl->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
    media_entity_init(&pmic_ctrl->subdev.entity, 0, NULL, 0);
    pmic_ctrl->subdev.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
    pmic_ctrl->subdev.entity.group_id = HWCAM_SUBDEV_PMIC;
    pmic_ctrl->subdev.entity.name = pmic_ctrl->subdev.name;
    hwcam_cfgdev_register_subdev(&pmic_ctrl->subdev);
    rc = pmic_ctrl->func_tbl->pmic_register_attribute(pmic_ctrl,
            &pmic_ctrl->subdev.devnode->dev);
    if (rc < 0) {
        cam_err("%s failed to register pmic attribute node.", __func__);
        return rc;
    }

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
    /* detect current device successful, set the flag as present */
    set_hw_dev_flag(DEV_I2C_CAMERA_PMU);
#endif
    hisi_set_pmic_ctrl(pmic_ctrl);
    return rc;
}
static int fsa9685_probe(
    struct i2c_client *client, const struct i2c_device_id *id)
{
    int ret = 0, reg02, reg04, reg08, reg09, gpio_value;
    struct device_node *node = client->dev.of_node;

    printk(KERN_INFO "%s++\n", __func__);

#if USE_DTS
    gpio = of_get_named_gpio(node, "fairchild_fsa9685,gpio-intb", 0);
#endif
#if USE_BOARDID
    get_hw_config_int("usb/gpio_intb", &gpio, NULL);
#endif
    printk(KERN_INFO "%s gpio_intb=%d\n", __func__, gpio);
    if (gpio < 0) {
        ret = ERRNUM_OF_GET_NAME_GPIO;
        return ret;
    }

    if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
        printk(KERN_ERR "%s i2c check fail\n", __func__);
        ret = -ENODEV;
        this_client = NULL;
        goto check_funcionality_failed;
    }
    this_client = client;

    INIT_WORK(&g_detach_work, fsa9685_detach_work);
    g_detach_work_init = 1;
    INIT_WORK(&g_reset_work, fsa9685_reset_work);

#ifdef CONFIG_FSA9685_DEBUG_FS
    ret = device_create_file(&client->dev, &dev_attr_dump_regs);
        if (ret < 0) {
            printk(KERN_ERR "%s create dev file fail %d\n", __func__, ret);
            ret = ERRNUM_SWITCH_USB_DEV_REGISTER;
            goto err_switch_usb_dev_register;
        }
#endif


#if PLAT_K3V3
    client->irq = gpio_to_irq(gpio);
#endif
#if PLAT_V9R1
    client->irq = IRQ_GPIO(gpio);
#endif
    if (client->irq < 0) {
        printk(KERN_ERR "%s get irq fail\n", __func__);
        ret = ERRUNM_GPIO_TO_IRQ;
        goto err_gpio_to_irq;
    }

    ret = gpio_request(gpio, "fsa9685_int");
    if (ret < 0) {
        printk(KERN_ERR "%s request gpio:%d fail\n", __func__, gpio);
        ret = ERRNUM_GPIO_REQUEST;
        goto err_gpio_request;
    }

    ret = gpio_direction_input(gpio);
    if (ret < 0) {
        printk(KERN_ERR "%s set dir %d fail\n", __func__, gpio);
        ret = ERRNUM_GPIO_DIRECTION_INPUT;
        goto err_gpio_direction_input;
    }
    reg08 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_1);
    reg09 = fsa9685_read_reg(FSA9685_REG_DEVICE_TYPE_2);
    printk(KERN_INFO "%s: reg08=0x%x reg09=0x%x.\n", __func__, reg08, reg09);
    if(!( (reg08 & (FSA9685_USB_DETECTED| FSA9685_MHL_DETECTED| FSA9685_CDP_DETECTED| FSA9685_DCP_DETECTED/*| FSA9685_USBOTG_DETECTED*/)) || (reg09 & FSA9685_JIG_UART) ) ) {
         printk(KERN_INFO "%s: no valid device,start reset \n", __func__);
	 ret = fsa9685_write_reg(FSA9685_REG_RESET, 0x89);
         if ( ret < 0 )
             printk(KERN_ERR "%s: error write iic reg" ,__func__);
    }
    /* interrupt register */
    INIT_WORK(&g_intb_work, fsa9685_intb_work);
#ifndef USE_LEVEL_IRQ
    ret = request_irq(client->irq,
               fsa9685_irq_handler,
               IRQF_TRIGGER_FALLING,
               "fsa9685_int", client);
#endif
    if (ret < 0) {
        printk(KERN_ERR "%s request thread irq %d fail\n", __func__, ret);
        ret = ERRNUM_REQUEST_THREADED_IRQ;
        goto err_request_threaded_irq;
    }
    /* clear INT MASK */
    reg02 = fsa9685_read_reg(FSA9685_REG_CONTROL);
    reg04 = fsa9685_read_reg(FSA9685_REG_INTERRUPT_MASK);
    printk(KERN_INFO "%s: fsa9685_read_reg(FSA9685_REG_CONTROL) reg02=0x%x reg04=0x%x.\n", __func__, reg02, reg04);
    reg02 &= (~FSA9685_INT_MASK);
    ret = fsa9685_write_reg(FSA9685_REG_CONTROL, reg02);
    if(ret<0){
        printk(KERN_ERR "%s write iic reg02 %d\n", __func__, ret);
        goto err_i2c_write;
    }

    gpio_value = gpio_get_value(gpio);
    printk(KERN_INFO "%s intb=%d after clear MASK\n", __func__, gpio_value);

#ifdef USE_LEVEL_IRQ
    ret = request_threaded_irq(client->irq, NULL,
               fsa9685_irq_handler,
               IRQF_TRIGGER_LOW | IRQF_ONESHOT,
               "fsa9685_int", client);
#endif

#ifndef USE_LEVEL_IRQ
    schedule_work(&g_intb_work);
#endif

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
    set_hw_dev_flag(DEV_I2C_USB_SWITCH);
#endif


    goto ret_val;

err_i2c_write:
err_request_threaded_irq:
err_gpio_direction_input:
    gpio_free(gpio);
err_gpio_request:
err_gpio_to_irq:
err_of_get_named_gpio:
err_switch_usb_dev_register:
check_funcionality_failed:

ret_val:
    printk(KERN_INFO "%s-- ret = %d.\n",__func__, ret);
    return ret;
}
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  mma8452_probe(struct i2c_client *client ,
                                  const struct i2c_device_id *id)
{
    int err=-1,client_id;
    struct i2c_adapter *adapter;
    struct gs_mma8452_data *mma;
    struct mma8452_acc_platform_data *devpd =client->dev.platform_data;
    pr_info("%s: probe start.\n", MMA8452_ACC_DEV_NAME);

    if (!devpd)
    {
        dev_err(&client->dev, "No platfrom data!\n");
        err=-ENODEV;
        goto err_get_power_fail;
    }
    /*get power*/
    if(devpd->power_on)
    {
        err = devpd->power_on(&client->dev);
        if(err < 0)
        {
            dev_err(&client->dev, "mma8452_acc_probe: get power fail! result=%d\n", err);
            goto err_get_power_fail;
        }
        dev_dbg(&client->dev,"mma8452_acc_probe: get power success! \n");
    }
    dev_info(&client->dev, "mma8452_acc_probe: get power success! result=%d\n", err);

    /*check functionality*/
    adapter = to_i2c_adapter(client->dev.parent);
    err = i2c_check_functionality(adapter,
                     I2C_FUNC_SMBUS_BYTE |
                     I2C_FUNC_SMBUS_BYTE_DATA);
    if (!err)
    {
        dev_err(&client->dev, "client not i2c capable\n");
        err=-ENODEV;
        goto err_out;
    }

    msleep(5);

    client_id = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);     // MMA8452_WHO_AM_I=3A
    if (client_id != MMA8452_ID)
    {
        dev_err(&client->dev,
            "read chip ID 0x%x is not equal to 0x%x or 0x%x!\n",
            err, MMA8452_ID, MMA8452_ID);
        err = -EINVAL;
        goto err_out;
    }
	dev_info(&client->dev, "Read mma8452 chip ok, ID is 0x%x\n", client_id);
	err = set_sensor_chip_info(ACC, "FREESCALE MMA8452");
	if (err) {
		dev_err(&client->dev, "set_sensor_chip_info error \n");
	}
    /*allocate memory*/
    mma=kzalloc(sizeof(struct gs_mma8452_data), GFP_KERNEL);
    if (!mma)
    {
        err = -ENOMEM;
        dev_err(&client->dev,
                "failed to allocate memory for module data: "
                    "%d\n",err);
        goto err_out;
    }
	err =  i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG3, 0x2);
	if (err < 0) {
		dev_err(&client->dev, "%s: failed to selects the polarity of the interrupt signal\n", __func__);
		goto err_out;
	}
    mutex_init(&mma->lock);
    mma->client=client;
    i2c_set_clientdata(client,mma);
    /* Initialize the MMA8452 chip */
    err = mma8452_hw_init(mma);      // MOD_2G     0
    if (err<0)
    {
        dev_err(&client->dev,
            "error mma8452_hw_init init chip failed:(%d)\n", err);
        goto err_init;
    }

    /*Initialize the input device */
    err=mma8452_input_init(mma);
    if(err<0)
    {
        dev_err(&client->dev,"input init failed \n");
        goto err_init;
    }

    err = create_sysfs_interfaces(&client->dev);
    if (err < 0)
    {
        dev_err(&client->dev, "device MMA8452_ACC_DEV_NAME sysfs register failed\n");
        goto err_create_sysfs;
    }
    dev_info(&client->dev, "create_sysfs_interfaces: create interfaces success! ");
    mma->mma_status.position = devpd->config_mxc_mma_position;

    #ifdef CONFIG_HAS_EARLYSUSPEND
    mma->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
    mma->early_suspend.suspend = mma8452_early_suspend;
    mma->early_suspend.resume = mma8452_early_resume;
    register_early_suspend(&mma->early_suspend);
    #endif
#ifdef CONFIG_HUAWEI_HW_DEV_DCT
        /* detect current device successful, set the flag as present */
    set_hw_dev_flag(DEV_I2C_G_SENSOR);
#endif
    pr_info("%s: probe success.\n", MMA8452_ACC_DEV_NAME);
    return 0;

err_create_sysfs:
       remove_sysfs_interfaces(&client->dev);
       input_unregister_device(mma->input_dev);
       input_free_device(mma->input_dev);
err_init:
    kfree(mma);
err_out:
    if(devpd->power_off)
          devpd->power_off();
err_get_power_fail:
    return err;
}
static int tps65132_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int retval = 0;
	int nRet = 0;
	int vpos_target = 0;
	int vneg_target = 0;
	struct device_node *np = NULL;
	struct tps65132_device_info *di = NULL;

	np = of_find_compatible_node(NULL, NULL, DTS_COMP_TPS65132);
	if (!np) {
		pr_err("NOT FOUND device node %s!\n", DTS_COMP_TPS65132);
		retval = -ENODEV;
		goto failed_1;
	}

	gpio_vsp_enable = of_get_named_gpio(np, "gpios", 0);
	gpio_vsn_enable = of_get_named_gpio(np, "gpios", 1);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("[%s,%d]: need I2C_FUNC_I2C\n",__FUNCTION__,__LINE__);
		retval = -ENODEV;
		goto failed_1;
	}

	di = kzalloc(sizeof(*di), GFP_KERNEL);
	if (!di) {
		dev_err(&client->dev, "failed to allocate device info data\n");
		retval = -ENOMEM;
		goto failed_1;
	}

	i2c_set_clientdata(client, di);
	di->dev = &client->dev;
	di->client = client;

	if (!fastboot_display_enable) {
		tps65132_start_setting();
	}

	tps65132_get_target_voltage(&vpos_target, &vneg_target);

	nRet = tps65132_reg_inited(di->client, (u8)vpos_target, (u8)vneg_target);
	if (nRet > 0) {
		pr_info("tps65132 inited needn't reset value\n");
	} else if (nRet < 0) {
		pr_err("tps65132 I2C read fail\n");
		retval = -ENODEV;
#if defined (CONFIG_HUAWEI_DSM)
		if (!dsm_client_ocuppy(lcd_dclient)) {
			dsm_client_record(lcd_dclient, "tps65132 I2C read fail\n");
			dsm_client_notify(lcd_dclient, DSM_LCD_POWER_STATUS_ERROR_NO);
		}
#endif
		goto failed_2;
	} else {
		nRet = tps65132_reg_init(di->client, (u8)vpos_target, (u8)vneg_target);
		if (nRet) {
			pr_err("tps65132_reg_init failed\n");
			retval = -ENODEV;
#if defined (CONFIG_HUAWEI_DSM)
			if (!dsm_client_ocuppy(lcd_dclient)) {
				dsm_client_record(lcd_dclient, "tps65132_reg_init failed\n");
				dsm_client_notify(lcd_dclient, DSM_LCD_POWER_STATUS_ERROR_NO);
			}
#endif
			goto failed_2;
		}
		pr_info("tps65132 inited succeed\n");
	}

	#ifdef CONFIG_HUAWEI_HW_DEV_DCT
		/* detect current device successful, set the flag as present */
		set_hw_dev_flag(DEV_I2C_DC_DC);
	#endif

failed_2:
	if (!fastboot_display_enable) {
		tps65132_finish_setting();
	}

	if (di)
		kfree(di);

failed_1:
	return retval;
}
Example #8
0
static int __devinit pn544_probe(struct i2c_client *client,
								 const struct i2c_device_id *id)
{
	int ret=0;
    /*del 10 lines*/
	
	PN544_DEBUG("%s:entered\n",__func__);

	/* private data allocation */ 
	pn544_info = kzalloc(sizeof(struct pn544_info), GFP_KERNEL); 
	if (!pn544_info) 
	{ 
		printk("%s:Cannot allocate memory for pn544_info.\n",__func__); 
		ret = -ENOMEM; 
		goto err_info_alloc; 
	} 

	pn544_info->buflen = max(PN544_MSG_MAX_SIZE, PN544_MAX_I2C_TRANSFER); 
	pn544_info->buf = kzalloc(pn544_info->buflen, GFP_KERNEL);    
	if (!pn544_info->buf) 
	{ 
		printk("%s:Cannot allocate memory for pn544_info->buf.\n",__func__); 
		ret = -ENOMEM; 
		goto err_buf_alloc; 
	} 

	pn544_info->i2c_dev = client; 
	pn544_info->state = PN544_ST_COLD; 
	pn544_info->read_irq = PN544_NONE; 
	mutex_init(&pn544_info->read_mutex); 
	mutex_init(&pn544_info->mutex); 
	mutex_init(&pn544_info->mutex_mmi); 
	init_waitqueue_head(&pn544_info->read_wait); 
	spin_lock_init(&pn544_info->irq_enabled_lock);
	i2c_set_clientdata(client, pn544_info); 
//On platform 7X30 we should identify whether GPIO04 is used
#ifdef CONFIG_ARCH_MSM7X30
    if (machine_is_msm8255_u8860_r())
	{
	    //GPIO04 is needed for firmware download
	    ret = init_fw_download();
	    if(ret) {
		    printk("%s:nfc init_fw_download failed\n",__func__);
	    }
	}
#else	
	ret = init_fw_download();
	if(ret) {
		printk("%s:nfc init_fw_download failed\n",__func__);
	}
#endif
	pdata = client->dev.platform_data; 
	if (!pdata) 
	{ 
		printk("%s:No platform data\n",__func__); 
		ret = -EINVAL; 
		goto err_no_platform_data; 
	} 
//The clock control of nfc is different between 7x27A and 7x30, we don't need to do following operation on 7X30 
#ifdef CONFIG_ARCH_MSM7X30
	/* nothing todo */
#else
	if (!pdata->pn544_clock_output_ctrl) 
	{ 
		printk("%s:pn544_clock_output_ctrl  missing\n",__func__); 
		ret = -EINVAL; 
		goto err_no_clock_ctrl; 
	} 
	else
	{
		ret = pdata->pn544_clock_output_ctrl(1);
		printk("pn544_clock_output_ctrl:%d \n",ret);
		if(ret)
		{		       
		    goto err_no_clock_ctrl; 
		}
	}    
	//It is a fixed operation sequence, just follow it   
	if (!pdata->pn544_fw_download_pull_down) 
	{ 
		printk("%s:fw_download  missing\n",__func__); 
		ret = -EINVAL; 
		goto err_no_fw_download; 
	} 
	else
	{
		ret = pdata->pn544_fw_download_pull_down();
		if(ret)
		{
			goto err_no_fw_download; 
		}
	}
#endif

	if (!pdata->pn544_ven_reset) 
	{ 
		printk("%s:ven reset missing\n",__func__); 
		ret = -EINVAL; 
		goto err_no_ven_reset; 
	} 
	else
	{
		ret = pdata->pn544_ven_reset();
		if(ret)
		{
			goto err_no_ven_reset; 
		}
	}
    /* we need to request read irq to support the pn544 
     *read function anyway , so we delete "if" here
     */
	if (!pdata->pn544_interrupt_gpio_config) 
	{ 
		printk("%s:request_resources() missing\n",__func__); 
		ret = -EINVAL; 
		goto err_gpio_config; 
	} 
	else
	{
		ret=pdata->pn544_interrupt_gpio_config();
		if(ret)
		{
			goto err_gpio_config; 
		}
	}

	/* irq request move down */
    /* we need to request read irq to support the pn544 
     *read function anyway , so we delete "if" here
     */

    //we use a func to deal the device probe
    if (pn544_i2c_device_probe(client) < 0)
    {
        printk("%s:unable to probe device.\n", __func__); 
		ret = -ENODEV; 
        goto err_cmd_resp;
    }
	/*kfree delete*/
	memcpy(&pn544_client,client,sizeof(struct i2c_client));

	if (0!=pn544_use_read_irq)
	{
		pn544_info->read_irq=PN544_NONE;
		enable_irq(pn544_client.irq);
		pn544_info->use_read_irq=1;
	}
	else
	{
		pn544_info->use_read_irq=0;
	}
	/* add irq request*/
	pn544_info->irq_enabled = true;
	ret = request_irq(client->irq, pn544_irq_thread_fn, 
		IRQF_TRIGGER_HIGH, PN544_DRIVER_NAME, pn544_info); 

	if (ret < 0) 
	{ 
		printk("%s:Unable to register IRQ handler\n", __func__); 
		goto err_irq_req; 
	} 
	pn544_disable_irq(pn544_info);
	pn544_info->miscdev.minor = MISC_DYNAMIC_MINOR; 
	pn544_info->miscdev.name = PN544_DRIVER_NAME; 
	pn544_info->miscdev.fops = &pn544_fops; 
	pn544_info->miscdev.parent = &client->dev; 
	ret = misc_register(&pn544_info->miscdev); 
	if (ret < 0) 
	{ 
		printk("%s:Device registration failed\n",__func__); 
		goto err_misc_dev; 
	} 

	/* remove code because the HAL and the up-level
	 * code added to our project
	 */
	printk("%s success finished: info: %p, client %p\n", 
		__func__, pn544_info, client); 

    #ifdef CONFIG_HUAWEI_HW_DEV_DCT
    /* detect current device successful, set the flag as present */
    set_hw_dev_flag(DEV_I2C_NFC);
    #endif

	ret = pn544_mmi_init();
	if (ret)
	{
		goto err_mmi_error;
	}

//following operation is for power save	
#ifdef CONFIG_ARCH_MSM7X30
	/* nothing todo */
#else
	ret = pdata->pn544_clock_output_ctrl(0);
	printk("pn544_clock_output_ctrl:%d \n",ret);
	if(ret)
	{		       
		goto err_clock_mode_ctrl_err; 
	}

	//It is another clock out put mode, we can see the difference with pn544_clock_output_ctrl() in board-msm7x27a.c
	if (!pdata->pn544_clock_output_mode_ctrl) 
	{ 
		printk("%s:pn544_clock_output_mode_ctrl  missing\n",__func__); 
		ret = -EINVAL; 
		goto err_clock_mode_ctrl_err; 
	} 
	else
	{
		// 1 - Set for clock PMU request mode , 0 - Close for clock PMU request mode
		ret = pdata->pn544_clock_output_mode_ctrl(1);
		printk("pn544_clock_output_mode_ctrl:%d \n",ret);
		if(ret)
		{		       
			goto err_clock_mode_ctrl_err; 
		}
	}
#endif
    
    /*del 4 lines*/
	return 0; 		
#ifdef CONFIG_ARCH_MSM7X30
	/* nothing todo */
#else
err_clock_mode_ctrl_err:	
#endif
err_mmi_error:
	misc_deregister(&pn544_info->miscdev);
err_misc_dev:
	free_irq(client->irq, pn544_info);
err_irq_req:
err_cmd_resp:
/*del 14 lines*/
err_gpio_config:

err_no_ven_reset:
#ifdef CONFIG_ARCH_MSM7X30
	/* nothing todo */
#else
err_no_fw_download:
	pdata->pn544_clock_output_ctrl(0);
    printk("pn544_clock_output_ctrl  close when error\n");
err_no_clock_ctrl:    
#endif
err_no_platform_data:
	mutex_destroy(&pn544_info->read_mutex); 
	mutex_destroy(&pn544_info->mutex); 
	mutex_destroy(&pn544_info->mutex_mmi); 
	kfree(pn544_info->buf); 

err_buf_alloc: 
	kfree(pn544_info); 

err_info_alloc: 

	return ret;
}
static int gs_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{	
	int ret = -1;
	struct gs_data *gs;

	printk("my gs_probe_lis3xh\n");
    
	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_int_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);

	printk("mode is %x\n", reg_read(gs, 0x20));
	gs->sub_type = reg_read(gs, 0x0f);
	printk("sub_type = %d\n", gs->sub_type);
	printk("gs is %s\n", (gs->sub_type==0x33)? "ST LIS3DH":"ST LIS331DLH");


	ret = reg_write(gs, GS_ST_REG_CTRL2, 0x00); /* device command = ctrl_reg2 */
	if (ret < 0) {
		printk(KERN_ERR "i2c_smbus_write_byte_data failed\n");
		/* fail? */
		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_STLIS3XH;

	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;
	
	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)
	{
		ret = -ENOMEM;
		printk("gs_probe: create_singlethread_workqueue error!");
		goto err_request_irq;
	}
	
	this_gs_data =gs;

    #ifdef CONFIG_HUAWEI_HW_DEV_DCT
    /* detect current device successful, set the flag as present */
    set_hw_dev_flag(DEV_I2C_G_SENSOR);
    #endif


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

	return 0;

err_request_irq:
#ifndef   GS_POLLING
	if (client->irq && gs->use_irq)
	{
		free_irq(client->irq, gs);
	}
#endif
	
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);


err_alloc_data_failed:
#ifndef   GS_POLLING 
	gs_free_int();
#endif

err_check_functionality_failed:
	return ret;
}
int32_t msm_sensor_driver_probe(void *setting,
	struct msm_sensor_info_t *probed_info, char *entity_name)
{
	int32_t                              rc = 0;
	struct msm_sensor_ctrl_t            *s_ctrl = NULL;
	struct msm_camera_cci_client        *cci_client = NULL;
	struct msm_camera_sensor_slave_info *slave_info = NULL;
	struct msm_camera_slave_info        *camera_info = NULL;
 
    struct msm_sensor_cam_id_t          *cam_id =NULL;
    
	unsigned long                        mount_pos = 0;
	int32_t index = -1;
	uint32_t                             i = 0;

	/* Validate input parameters */
	if (!setting) {
		pr_err("failed: slave_info %p", setting);
		return -EINVAL;
	}

	/* Allocate memory for slave info */
	slave_info = kzalloc(sizeof(*slave_info), GFP_KERNEL);
	if (!slave_info) {
		pr_err("failed: no memory slave_info %p", slave_info);
		return -ENOMEM;
	}
#ifdef CONFIG_COMPAT
	if (is_compat_task()) {
		struct msm_camera_sensor_slave_info32 setting32;
		if (copy_from_user((void *)&setting32, setting,
			sizeof(setting32))) {
				pr_err("failed: copy_from_user");
				rc = -EFAULT;
				goto free_slave_info;
			}

		strlcpy(slave_info->actuator_name, setting32.actuator_name,
			sizeof(slave_info->actuator_name));

		strlcpy(slave_info->eeprom_name, setting32.eeprom_name,
			sizeof(slave_info->eeprom_name));

		strlcpy(slave_info->sensor_name, setting32.sensor_name,
			sizeof(slave_info->sensor_name));

		strlcpy(slave_info->ois_name, setting32.ois_name,
			sizeof(slave_info->ois_name));

		strlcpy(slave_info->flash_name, setting32.flash_name,
			sizeof(slave_info->flash_name));

		slave_info->addr_type = setting32.addr_type;
		slave_info->camera_id = setting32.camera_id;

		slave_info->i2c_freq_mode = setting32.i2c_freq_mode;
		slave_info->sensor_id_info = setting32.sensor_id_info;

		slave_info->slave_addr = setting32.slave_addr;
		slave_info->power_setting_array.size =
			setting32.power_setting_array.size;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.size_down =
			setting32.power_setting_array.size_down;
		slave_info->power_setting_array.power_setting =
			compat_ptr(setting32.power_setting_array.power_setting);
		slave_info->power_setting_array.power_down_setting =
			compat_ptr(setting32.
				power_setting_array.power_down_setting);
		slave_info->is_init_params_valid =
			setting32.is_init_params_valid;
		slave_info->sensor_init_params = setting32.sensor_init_params;
		slave_info->is_flash_supported = setting32.is_flash_supported;
	} else
#endif
	{
		if (copy_from_user(slave_info,
					(void *)setting, sizeof(*slave_info))) {
			pr_err("failed: copy_from_user");
			rc = -EFAULT;
			goto free_slave_info;
		}
	}

	/* Print slave info */
	CDBG("camera id %d", slave_info->camera_id);
	CDBG("slave_addr 0x%x", slave_info->slave_addr);
	CDBG("addr_type %d", slave_info->addr_type);
	CDBG("sensor_id_reg_addr 0x%x",
		slave_info->sensor_id_info.sensor_id_reg_addr);
	CDBG("sensor_id 0x%x", slave_info->sensor_id_info.sensor_id);
	CDBG("size %d", slave_info->power_setting_array.size);
	CDBG("size down %d", slave_info->power_setting_array.size_down);
	/* Print dump reg info */
	CDBG("dump_reg_num:%d \n", slave_info->dump_reg_num);
	for(i = 0; i < slave_info->dump_reg_num; i++)
		CDBG("load dump_reg_addr:0x%X,default value:0x%X \n",
			slave_info->dump_reg_info[i].addr,
			slave_info->dump_reg_info[i].value);

	if (slave_info->is_init_params_valid) {
		CDBG("position %d",
			slave_info->sensor_init_params.position);
		CDBG("mount %d",
			slave_info->sensor_init_params.sensor_mount_angle);
	}

	/* Validate camera id */
	if (slave_info->camera_id >= MAX_CAMERAS) {
		pr_err("failed: invalid camera id %d max %d",
			slave_info->camera_id, MAX_CAMERAS);
		rc = -EINVAL;
		goto free_slave_info;
	}

	/* Extract s_ctrl from camera id */
	s_ctrl = g_sctrl[slave_info->camera_id];
	if (!s_ctrl) {
		pr_err("failed: s_ctrl %p for camera_id %d", s_ctrl,
			slave_info->camera_id);
		rc = -EINVAL;
		goto free_slave_info;
	}

	CDBG("s_ctrl[%d] %p", slave_info->camera_id, s_ctrl);

	if (s_ctrl->is_probe_succeed == 1) {
		/*
		 * Different sensor on this camera slot has been connected
		 * and probe already succeeded for that sensor. Ignore this
		 * probe
		 */
		if (slave_info->sensor_id_info.sensor_id ==
			s_ctrl->sensordata->cam_slave_info->
				sensor_id_info.sensor_id) {
			pr_err("slot%d: sensor id%d already probed\n",
				slave_info->camera_id,
				s_ctrl->sensordata->cam_slave_info->
					sensor_id_info.sensor_id);
			msm_sensor_fill_sensor_info(s_ctrl,
				probed_info, entity_name);
		} else
			pr_err("slot %d has some other sensor\n",
				slave_info->camera_id);

		rc = 0;
		goto free_slave_info;
	}

	if (s_ctrl->sensordata->special_support_size > 0) {
		if (!msm_sensor_driver_is_special_support(s_ctrl,
			slave_info->sensor_name)) {
			pr_err("%s:%s is not support on this board\n",
				__func__, slave_info->sensor_name);
			rc = 0;
			goto free_slave_info;
		}
	}

	rc = msm_sensor_get_power_settings(setting, slave_info,
		&s_ctrl->sensordata->power_info);
	if (rc < 0) {
		pr_err("failed");
		goto free_slave_info;
	}


	camera_info = kzalloc(sizeof(struct msm_camera_slave_info), GFP_KERNEL);
	if (!camera_info) {
		pr_err("failed: no memory slave_info %p", camera_info);
		goto free_slave_info;

	}

	s_ctrl->sensordata->slave_info = camera_info;
	
   	/* used for confirmed MCAM_ID */
	cam_id = kzalloc(sizeof(*cam_id),GFP_KERNEL);
	if(!cam_id){
		pr_err("failed: no memory cam_id %p",cam_id);
		rc = -ENOMEM;
		goto free_camera_info;
	}
	if(slave_info->sensor_cam_id){
		if (copy_from_user(cam_id,(void *)slave_info->sensor_cam_id,sizeof(*cam_id))) {
			pr_err("sensor_cam_id failed: copy_from_user");
			rc = -EFAULT;
			goto free_camera_id;
		}
		camera_info->mcam_id = cam_id->cam_excepted_id;
		CDBG("%s expect camera id %d",slave_info->sensor_name,camera_info->mcam_id);
	}else{
		CDBG("%s no need to match camera id",slave_info->sensor_name);
		camera_info->mcam_id = 2;
	}

	/* Fill sensor slave info */
	camera_info->sensor_slave_addr = slave_info->slave_addr;
	camera_info->sensor_id_reg_addr =
		slave_info->sensor_id_info.sensor_id_reg_addr;
	camera_info->sensor_id = slave_info->sensor_id_info.sensor_id;
        camera_info->sensor_id_data_type = slave_info->sensor_id_info.sensor_id_data_type;

	//Fill dump reg info
	if (0 !=  slave_info->dump_reg_num && slave_info->dump_reg_info) {
		camera_info->dump_reg_num = slave_info->dump_reg_num;
		camera_info->dump_reg_info = kzalloc( (sizeof (struct dump_reg_info_t)) *
			slave_info->dump_reg_num, GFP_KERNEL);

		if (!camera_info->dump_reg_info) {
			pr_err("failed: no memory dump reg info %p", camera_info->dump_reg_info);
			return -ENOMEM;
		} else if (copy_from_user(camera_info->dump_reg_info,slave_info->dump_reg_info,
					sizeof(struct dump_reg_info_t) * slave_info->dump_reg_num)) {
			pr_err("failed: copy_dump_reg");
			rc = -EFAULT;
			kfree(camera_info->dump_reg_info);
			return rc;
		} else {
			for(i = 0; i < (camera_info->dump_reg_num); i++)
				CDBG("cam_dump_reg: 0x%X",
				camera_info->dump_reg_info[i].addr);
		}
	} else {
		pr_err("sensor %s have no dump_reg_info",slave_info->sensor_name);
	}

	/* Fill CCI master, slave address and CCI default params */
	if (!s_ctrl->sensor_i2c_client) {
		pr_err("failed: sensor_i2c_client %p",
			s_ctrl->sensor_i2c_client);
		rc = -EINVAL;
		goto free_camera_info;
	}
	/* Fill sensor address type */
	s_ctrl->sensor_i2c_client->addr_type = slave_info->addr_type;
	if (s_ctrl->sensor_i2c_client->client)
		s_ctrl->sensor_i2c_client->client->addr =
			camera_info->sensor_slave_addr;

	cci_client = s_ctrl->sensor_i2c_client->cci_client;
	if (!cci_client) {
		pr_err("failed: cci_client %p", cci_client);
		goto free_camera_info;
	}
	cci_client->cci_i2c_master = s_ctrl->cci_i2c_master;
	cci_client->sid = slave_info->slave_addr >> 1;
	cci_client->retries = 3;
	cci_client->id_map = 0;
	cci_client->i2c_freq_mode = slave_info->i2c_freq_mode;

	/* Parse and fill vreg params for powerup settings */
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_setting,
		s_ctrl->sensordata->power_info.power_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_get_dt_power_setting_data rc %d",
			rc);
		goto free_camera_info;
	}

	/* Parse and fill vreg params for powerdown settings*/
	rc = msm_camera_fill_vreg_params(
		s_ctrl->sensordata->power_info.cam_vreg,
		s_ctrl->sensordata->power_info.num_vreg,
		s_ctrl->sensordata->power_info.power_down_setting,
		s_ctrl->sensordata->power_info.power_down_setting_size);
	if (rc < 0) {
		pr_err("failed: msm_camera_fill_vreg_params for PDOWN rc %d",
			rc);
		goto free_camera_info;
	}

	/* Update sensor, actuator and eeprom name in
	*  sensor control structure */
	s_ctrl->sensordata->sensor_name = slave_info->sensor_name;
	s_ctrl->sensordata->eeprom_name = slave_info->eeprom_name;
	s_ctrl->sensordata->actuator_name = slave_info->actuator_name;
	s_ctrl->sensordata->ois_name = slave_info->ois_name;
	/*
	 * Update eeporm subdevice Id by input eeprom name
	 */
	rc = msm_sensor_fill_eeprom_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}
	/*
	 * Update actuator subdevice Id by input actuator name
	 */
	rc = msm_sensor_fill_actuator_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

	rc = msm_sensor_fill_ois_subdevid_by_name(s_ctrl);
	if (rc < 0) {
		pr_err("%s failed %d\n", __func__, __LINE__);
		goto free_camera_info;
	}

	/* Power up and probe sensor */
	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
	if (rc < 0) {
		pr_err("%s power up failed", slave_info->sensor_name);
		goto free_camera_info;
	}
	if ( is_exist_otp_function(s_ctrl, &index)){
		if(otp_function_lists[index].is_boot_load){
			rc = otp_function_lists[index].sensor_otp_function(s_ctrl, index);
			if (rc < 0){
				pr_err("%s:%d failed rc %d\n", __func__,__LINE__, rc);
			}
		}
	}
	pr_err("%s probe succeeded", slave_info->sensor_name);
	if (0 == slave_info->camera_id){
		rc = app_info_set("camera_main", slave_info->sensor_name);
	}
	else if (1 == slave_info->camera_id){
		rc = app_info_set("camera_slave", slave_info->sensor_name);
	}
	else{
		pr_err("%s app_info_set id err", slave_info->sensor_name);
	}

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	if(0 == slave_info->camera_id) //detet main senor or sub sensor
	{
		set_hw_dev_flag(DEV_I2C_CAMERA_MAIN);   //set sensor flag
	}
	else if (1 == slave_info->camera_id)       //sub sensor
	{
		set_hw_dev_flag(DEV_I2C_CAMERA_SLAVE);  //set sensor flag
	}
	else
	{
		pr_err("%s set_hw_dev_flag id err", slave_info->sensor_name);
	}
#endif
	/*
	  Set probe succeeded flag to 1 so that no other camera shall
	 * probed on this slot
	 */
	s_ctrl->is_probe_succeed = 1;

	/*
	 * Update the subdevice id of flash-src based on availability in kernel.
	 */
	if (slave_info->is_flash_supported == 0) {
		s_ctrl->sensordata->sensor_info->
			subdev_id[SUB_MODULE_LED_FLASH] = -1;
	}

	/*
	 * Create /dev/videoX node, comment for now until dummy /dev/videoX
	 * node is created and used by HAL
	 */

	if (s_ctrl->sensor_device_type == MSM_CAMERA_PLATFORM_DEVICE)
		rc = msm_sensor_driver_create_v4l_subdev(s_ctrl);
	else
		rc = msm_sensor_driver_create_i2c_v4l_subdev(s_ctrl);
	if (rc < 0) {
		pr_err("failed: camera creat v4l2 rc %d", rc);
		goto camera_power_down;
	}

	/* Power down */
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);

	rc = msm_sensor_fill_slave_info_init_params(
		slave_info,
		s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Fill slave info failed", slave_info->sensor_name);
		goto free_camera_info;
	}
	rc = msm_sensor_validate_slave_info(s_ctrl->sensordata->sensor_info);
	if (rc < 0) {
		pr_err("%s Validate slave info failed",
			slave_info->sensor_name);
		goto free_camera_info;
	}
	/* Update sensor mount angle and position in media entity flag */
	mount_pos = s_ctrl->sensordata->sensor_info->position << 16;
	mount_pos = mount_pos | ((s_ctrl->sensordata->sensor_info->
		sensor_mount_angle / 90) << 8);
	s_ctrl->msm_sd.sd.entity.flags = mount_pos | MEDIA_ENT_FL_DEFAULT;

	/*Save sensor info*/
	s_ctrl->sensordata->cam_slave_info = slave_info;

	msm_sensor_fill_sensor_info(s_ctrl, probed_info, entity_name);

	return rc;

camera_power_down:
	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
free_camera_info:
	kfree(camera_info);
free_camera_id:
	kfree(cam_id);
free_slave_info:
	kfree(slave_info);
	return rc;
}
int msm_flash_i2c_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int rc = 0;
#ifdef CONFIG_HUAWEI_HW_DEV_DCT
      uint16_t tmp_data = 0;
#endif
	struct msm_led_flash_ctrl_t *fctrl = NULL;
#ifdef CONFIG_DEBUG_FS
	struct dentry *dentry;
#endif
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("i2c_check_functionality failed\n");
		goto probe_failure;
	}
    if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
	{
	    pr_err("i2c_check_functionality failed I2C_FUNC_SMBUS_I2C_BLOCK\n");
		goto probe_failure;
	}

	fctrl = (struct msm_led_flash_ctrl_t *)(id->driver_data);
	if (fctrl->flash_i2c_client)
		fctrl->flash_i2c_client->client = client;
	/* Set device type as I2C */
	fctrl->flash_device_type = MSM_CAMERA_I2C_DEVICE;

	/* Assign name for sub device */
	snprintf(fctrl->msm_sd.sd.name, sizeof(fctrl->msm_sd.sd.name),
		"%s", id->name);

	rc = msm_led_get_dt_data(client->dev.of_node, fctrl);
	if (rc < 0) {
		pr_err("%s failed line %d\n", __func__, __LINE__);
		return rc;
	}
	if (fctrl->flash_i2c_client != NULL) {
		fctrl->flash_i2c_client->client = client;
		if (fctrl->flashdata->slave_info->sensor_slave_addr)
			fctrl->flash_i2c_client->client->addr =
				fctrl->flashdata->slave_info->
				sensor_slave_addr;
	} else {
		pr_err("%s %s sensor_i2c_client NULL\n",
			__func__, client->name);
		rc = -EFAULT;
		return rc;
	}

	fctrl->flash_i2c_client->client->addr = fctrl->flash_i2c_client->client->addr<<1;
	if (!fctrl->flash_i2c_client->i2c_func_tbl)
		fctrl->flash_i2c_client->i2c_func_tbl =
			&msm_sensor_qup_func_tbl;

#ifdef CONFIG_HUAWEI_HW_DEV_DCT
    /* read chip id */
    //clear the err and unlock IC, this function must be called before read and write register
    msm_flash_clear_err_and_unlock(fctrl);

    rc = fctrl->flash_i2c_client->i2c_func_tbl->i2c_read(
                fctrl->flash_i2c_client,0x00,&tmp_data, MSM_CAMERA_I2C_BYTE_DATA);
    if(rc < 0)
    {
        pr_err("%s: FLASHCHIP READ I2C error!\n", __func__);
        goto probe_failure;
    }

    if ( FLASH_CHIP_ID == (tmp_data & FLASH_CHIP_ID_MASK) )
    {
        pr_err("%s : Read chip id ok!Chip ID is %d.\n", __func__, tmp_data);
        /* detect current device successful, set the flag as present */
        set_hw_dev_flag(DEV_I2C_FLASH);
        pr_err("%s : LM3642 probe succeed!\n", __func__);
    }
    else
    {
        pr_err("%s : read chip id error!Chip ID is %d.\n", __func__, tmp_data);
        rc = -ENODEV;
        goto probe_failure;
    }
#endif

	rc = msm_led_i2c_flash_create_v4lsubdev(fctrl);
#ifdef CONFIG_DEBUG_FS
	dentry = debugfs_create_file("ledflash", S_IRUGO, NULL, (void *)fctrl,
		&ledflashdbg_fops);
	if (!dentry)
		pr_err("Failed to create the debugfs ledflash file");
#endif
	CDBG("%s:%d probe success\n", __func__, __LINE__);
	return 0;

probe_failure:
	CDBG("%s:%d probe failed\n", __func__, __LINE__);
	return rc;
}
Example #12
0
static int aps_12d_probe(
	struct i2c_client *client, const struct i2c_device_id *id)
{	
	int ret;
	struct aps_data *aps;
	int i;

	printk(KERN_INFO "aps_12d_probe enter\n ");
	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(machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150())
	{
		if((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 c8150 and u8150 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);

	printk(KERN_INFO "aps_12d_probe send command 2\n ");
	/* Command 2 register: 25mA,DC,12bit,Range1 */
	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));
	if (ret < 0) {
		goto err_detect_failed;
	}

	if( machine_is_msm7x25_u8150() || machine_is_msm7x25_c8150() || machine_is_msm7x25_u8159()\
		|| machine_is_msm7x25_u8160() || machine_is_msm7x25_u8130() || machine_is_msm7x25_c8510())
	{
		range_index = 0;
		high_threshold = high_threshold_value[range_index];
		low_threshold = low_threshold_value[range_index];


		for(i = 0; i < TOTAL_RANGE_NUM; i++)
		{
			/* NOTE: do NOT use the last one */
			up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value[i] - UP_RANGE_FIX;
#ifdef DEBUG_AUTO_RANGE_ADJUST
			printk("up_range_value[%d] = %d.\n",i, up_range_value[i]);
#endif
		}

		down_range_value[0] = 0;
		for(i = 1; i < TOTAL_RANGE_NUM; i++)
		{
			/* NOTE: do not use the first one */
			down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4;
#ifdef DEBUG_AUTO_RANGE_ADJUST
			printk("down_range_value[%d] = %d\n",i, down_range_value[i]);
#endif
		}

	}
	else if( machine_is_msm7x25_u8500() || machine_is_msm7x25_um840())
	{
		high_threshold = 300;
		low_threshold = 280;
	}
	else if( machine_is_msm7x25_u8300() )
	{
/* set shutter value for u8300 */
		high_threshold = 710;
		low_threshold = 650;
	}
	else
	{
		high_threshold = 780;
		low_threshold = 730;
	}
	
	if (sensor_dev == NULL) {
		aps->input_dev = input_allocate_device();
		if (aps->input_dev == NULL) {
			ret = -ENOMEM;
			printk(KERN_ERR "aps_12d_probe: Failed to allocate input device\n");
			goto err_input_dev_alloc_failed;
		}
		aps->input_dev->name = "sensors";
		
		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;
		}
		sensor_dev = aps->input_dev;
	} else {
		aps->input_dev = sensor_dev;
	}

	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;

#ifdef CONFIG_HAS_EARLYSUSPEND
	aps->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	aps->early_suspend.suspend = aps_12d_early_suspend;
	aps->early_suspend.resume = aps_12d_early_resume;
	register_early_suspend(&aps->early_suspend);
#endif

	#ifdef CONFIG_HUAWEI_HW_DEV_DCT
	/* detect current device successful, set the flag as present */
	set_hw_dev_flag(DEV_I2C_APS);
	#endif

	printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n");

#ifdef CONFIG_MELFAS_UPDATE_TS_FIRMWARE
	TS_updateFW_aps_data = this_aps_data;
	TS_updateFW_aps_wq = aps_wq;
#endif

	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:
	return ret;
  
}
Example #13
0
/*<BU5D08118 zhangtao 20100419 begin*/
static int aps_12d_probe(
	
	struct i2c_client *client, const struct i2c_device_id *id)
{	
	int ret;
	struct aps_data *aps;
	/*the aps_12d sensors ispower on*/
	/* <BU5D07679 zhangtao 20100413 begin */
	struct vreg *vreg_gp4=NULL;
	int rc;
/* <DTS2010100800714 liugaofei 20101008 begin */
	int i;
/* DTS2010100800714 liugaofei 20101008 end */
	
    vreg_gp4 = vreg_get(NULL, VREG_GP4_NAME);
    /* < DTS2010061200552 zhangtao 20100612 begin */
    if (IS_ERR(vreg_gp4)) 
    {
	    pr_err("%s:gp4 power init get failed\n", __func__);
    }
    /* DTS2010061200552 zhangtao 20100612 end> */

    /* <DTS2011012600839 liliang 20110215 begin */
    /* set gp4 voltage as 2700mV for all */
    rc = vreg_set_level(vreg_gp4,VREG_GP4_VOLTAGE_VALUE_2700);
    /* <DTS2011012600839 liliang 20110215 end >*/
    
	if (rc) {
		PROXIMITY_DEBUG("%s: vreg_gp4  vreg_set_level failed \n", __func__);
		return rc;
	}
	rc = vreg_enable(vreg_gp4);
	if (rc) {
		pr_err("%s: vreg_gp4    vreg_enable failed \n", __func__);
		return rc;
	}
	mdelay(5);
       /* BU5D07679 zhangtao 20100413 end> */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		PROXIMITY_DEBUG(KERN_ERR "aps_12d_probe: need I2C_FUNC_I2C\n");
		ret = -ENODEV;
		goto err_check_functionality_failed;
	}

	/* < DTS2010091001474 zhangtao 20100910 begin */
	/* if querry the board is T1 or T2 turn off the proximity */
    /*< DTS2010092400487  lijianzhao 20100924 begin */
    /* 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; 
	}    
    /* DTS2010092400487  lijianzhao 20100924 end >*/ 
	/* DTS2010091001474 zhangtao 20100910 end > */

	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 */

	/* < DTS2010081803338 zhangtao 20100818 begin */
	/* make the rang smaller can make the ir changge bigger */
	ret = aps_i2c_reg_write(aps, APS_12D_REG_CMD2, \
/* < DTS2010102103994 zhangtao 20101112 begin */
	                         (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));
/* DTS2010102103994 zhangtao 20101112 end > */
	/* DTS2010081803338 zhangtao 20100818 end > */
	if(ret < 0)
	{
		goto err_detect_failed;
	}
/* <DTS2010100800714 liugaofei 20101008 begin */
	range_index = 0;

	for(i = 0; i < TOTAL_RANGE_NUM; i++)
	{
		/* NOTE: do NOT use the last one */
		up_range_value[i] = MAX_ADC_OUTPUT - high_threshold_value[i] - RANGE_FIX; 
	}

	down_range_value[0] = 0;
	for(i = 1; i < TOTAL_RANGE_NUM; i++)
	{
		/* NOTE: do not use the first one */
		down_range_value[i] = (MAX_ADC_OUTPUT - high_threshold_value[i-1] - (MAX_ADC_OUTPUT / ADJUST_GATE)) / 4; 
	}
/* DTS2010100800714 liugaofei 20101008 end */

	/* < DTS2011042705601 zhangtao 20110427 begin */
	/*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;
	}
	/* DTS2011042705601 zhangtao 20110427 end > */
	
	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;
	}

	/* < DTS2010090300997 zhangtao 20100903 begin */

	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");
	/* DTS2010090300997 zhangtao 20100903 end > */


	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;

    /* <DTS2011032104626 shenjinming 20110321 begin */
    #ifdef CONFIG_HUAWEI_HW_DEV_DCT
    /* detect current device successful, set the flag as present */
    set_hw_dev_flag(DEV_I2C_APS);
    #endif
    /* <DTS2011032104626 shenjinming 20110321 end> */
/* < DTS2011052606009 jiaxianghong 20110527 end */	  

	printk(KERN_INFO "aps_12d_probe: Start Proximity Sensor APS-12D\n");
/* DTS2010072801000 zhangtao 20100728 end > */

	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:
/* < DTS2010061200552 zhangtao 20100612 begin */
	if(NULL != vreg_gp4)
	{
	    /* < DTS2011052101089 shenjinming 20110521 begin */
        /* can't use the flag ret here, it will change the return value of probe function */
        vreg_disable(vreg_gp4);
        /* delete a line */
        /* DTS2011052101089 shenjinming 20110521 end > */
	}
/* DTS2010061200552 zhangtao 20100612 end > */
	return ret;
  
}