static int ltr558_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; struct ltr558_info *lpi; struct ltr558_platform_data *pdata; D("[ltr558] %s\n", __func__); lpi = kzalloc(sizeof(struct ltr558_info), GFP_KERNEL); if (!lpi) return -ENOMEM; /*D("[ltr558] %s: client->irq = %d\n", __func__, client->irq);*/ lpi->i2c_client = client; pdata = client->dev.platform_data; if (!pdata) { pr_err("[ltr558 error]%s: Assign platform_data error!!\n",__func__); ret = -EBUSY; goto err_platform_data_null; } /*start to declare regulator and enable power*/ lpi->ls_regulator = regulator_get(NULL, "hcldo1_3v3"); if (!lpi->ls_regulator || IS_ERR(lpi->ls_regulator)) { printk(KERN_ERR "ltr558 No Regulator available\n"); ret = -EFAULT; goto err_platform_data_null; } if(lpi->ls_regulator){ regulator_set_voltage(lpi->ls_regulator,3300000,3300000); regulator_enable(lpi->ls_regulator);/*enable power*/ } //[email protected] 2011.12.21 begin //check device ID uint8_t device_id = 0; ret = ltr558_i2c_read(LTR558_MANUFACTURER_ID,&device_id); if((device_id == 0x05)||(!ret)) { printk("=====ltr558 device found!!====\n"); } else { printk("ltr558 device no found error!! id = %x\n",device_id); goto err_platform_data_null; } //[email protected] 2011.12.21 end lpi->irq = client->irq; i2c_set_clientdata(client, lpi); //ltr558_devinit(); // if (ret) { // printk("ltr558 device init failed.\n"); //} pdata->init();/*init sensor gpio interrupt pin*/ lp_info = lpi; mutex_init(&als_enable_mutex); mutex_init(&als_disable_mutex); mutex_init(&als_get_adc_mutex); ret = lightsensor_setup(lpi); if (ret < 0) { pr_err("[ltr558 error]%s: lightsensor_setup error!!\n",__func__); goto err_lightsensor_setup; } ret = psensor_setup(lpi); if (ret < 0) { pr_err("[ltr558 error]%s: psensor_setup error!!\n",__func__); goto err_psensor_setup; } lpi->lp_wq = create_singlethread_workqueue("ltr558_wq"); if (!lpi->lp_wq) { pr_err("[ltr558 error]%s: can't create workqueue\n", __func__); ret = -ENOMEM; goto err_create_singlethread_workqueue; } wake_lock_init(&(lpi->ps_wake_lock), WAKE_LOCK_SUSPEND, "proximity"); ret = ltr558_setup(lpi); if (ret < 0) { pr_err("[ltr558 error]%s: ltr558_setup error!\n", __func__); goto err_ltr558_setup; } lpi->ltr558_class = class_create(THIS_MODULE, "optical_sensors"); if (IS_ERR(lpi->ltr558_class)) { ret = PTR_ERR(lpi->ltr558_class); lpi->ltr558_class = NULL; goto err_create_class; } lpi->ls_dev = device_create(lpi->ltr558_class, NULL, 0, "%s", "lightsensor"); if (unlikely(IS_ERR(lpi->ls_dev))) { ret = PTR_ERR(lpi->ls_dev); lpi->ls_dev = NULL; goto err_create_ls_device; } /* register the attributes */ ret = device_create_file(lpi->ls_dev, &dev_attr_als_enable); if (ret) goto err_create_ls_device_file; lpi->ps_dev = device_create(lpi->ltr558_class, NULL, 0, "%s", "proximity"); if (unlikely(IS_ERR(lpi->ps_dev))) { ret = PTR_ERR(lpi->ps_dev); lpi->ps_dev = NULL; goto err_create_ps_device; } /* register the attributes */ ret = device_create_file(lpi->ps_dev, &dev_attr_ps_enable); if (ret) goto err_create_ps_device_file1; /* register the attributes */ lpi->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; lpi->early_suspend.suspend = ltr558_early_suspend; lpi->early_suspend.resume = ltr558_late_resume; register_early_suspend(&lpi->early_suspend); lpi->als_enable = 1; lpi->ps_enable = 1; lpi->ps_irq_flag = 0; ltr558_devinit(); D("[ltr558] %s: Probe success!\n", __func__); printk("[ltr558] Probe and setup success!\n"); return ret; err_create_ps_device_file1: device_unregister(lpi->ps_dev); err_create_ps_device: device_remove_file(lpi->ls_dev, &dev_attr_als_enable); err_create_ls_device_file: device_unregister(lpi->ls_dev); err_create_ls_device: class_destroy(lpi->ltr558_class); err_create_class: err_ltr558_setup: wake_lock_destroy(&(lpi->ps_wake_lock)); destroy_workqueue(lpi->lp_wq); err_create_singlethread_workqueue: free_irq(lpi->irq, lpi); input_unregister_device(lpi->ps_input_dev); input_free_device(lpi->ps_input_dev); misc_deregister(<r558_psensor_misc); err_psensor_setup: regulator_disable(lpi->ls_regulator);/*disable power*/ input_unregister_device(lpi->ls_input_dev); input_free_device(lpi->ls_input_dev); misc_deregister(&lightsensor_misc); err_lightsensor_setup: mutex_destroy(&als_enable_mutex); mutex_destroy(&als_disable_mutex); mutex_destroy(&als_get_adc_mutex); pdata->exit(NULL); /* free gpio request */ err_platform_data_null: kfree(lpi); return ret; }
static int ltr558_probe(struct i2c_client *client, const struct i2c_device_id *id){ int ret = 0; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); /* Return 1 if adapter supports everything we need, 0 if not. */ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE |I2C_FUNC_SMBUS_READ_BYTE_DATA)){ LTRERR(KERN_ALERT "%s: LTR-558ALS functionality check failed.\n", __func__); ret = -EIO; goto exit_check_functionality_failed; } /* data memory allocation */ ltr558_data = kzalloc(sizeof(struct ltr558_data), GFP_KERNEL); if (ltr558_data == NULL) { LTRERR(KERN_ALERT "%s: LTR-558ALS kzalloc failed.\n", __func__); ret = -ENOMEM; goto exit_alloc_data_failed; } ltr558_data->ltr558_irq = client->irq; //printk("%s: Irq number is == %d\n",client->irq); ltr558_data->p_enable = 0; ltr558_data->l_enable = 0; ltr558_data->ltr558_input = NULL; ltr558_data->client = client; INIT_WORK(&(ltr558_data->irq_workqueue),ltr558_schedwork); i2c_set_clientdata(client, ltr558_data); /*init device by send i2c command*/ ret = ltr558_devinit(); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS device init failed.\n", __func__); goto exit_device_init_failed; } /*init & register input dev*/ ltr558_data->ltr558_input = input_allocate_device(); if (ltr558_data->ltr558_input == NULL) { LTRERR(KERN_ALERT "%s: LTR-558ALS cllocate input device fail.\n", __func__); ret = -ENOMEM; goto exit_input_dev_alloc_failed; } ltr558_data->ltr558_input->name = "lightsensor"; set_bit(EV_ABS, ltr558_data->ltr558_input->evbit); input_set_abs_params(ltr558_data->ltr558_input, ABS_MISC, 0, 100000, 0, 0); input_set_abs_params(ltr558_data->ltr558_input, ABS_DISTANCE, 0, 128, 0, 0); ret = input_register_device(ltr558_data->ltr558_input); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS failed to register input device.\n", __func__); goto exit_input_register_device_failed; } /*register misc device*/ ret = misc_register(<r558_device); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS misc_register als failed.\n", __func__); goto exit_misc_device_register_failed; } /*init irq*/ ret = ltr558_gpio_irq(); if (ret) { LTRERR(KERN_ALERT "%s: LTR-558ALS gpio_irq failed.\n", __func__); goto exit_irq_request_failed; } #if 0 //add charles.hu just for test mdelay(600); ltr558_als_enable(ALS_RANGE2_64K); ltr558_ps_enable(PS_GAINRANGE); mdelay(600); P_L_printk("Ltr558 probe ok!!!\n"); //add end #endif return 0; exit_irq_request_failed: misc_deregister(<r558_device); exit_misc_device_register_failed: exit_input_register_device_failed: input_free_device(ltr558_data->ltr558_input); exit_input_dev_alloc_failed: exit_device_init_failed: kfree(ltr558_data); exit_alloc_data_failed: exit_check_functionality_failed: return ret; }