static struct i2c_driver apds9130_driver; static int __devinit apds9130_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct apds9130_data *data; int err = 0; printk(KERN_INFO "%s %d\n ",__func__,__LINE__); if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { err = -EIO; printk("apds9130 probe failed due to I2C_FUNC_SMBUS_BYTE. Ret = %d\n",err); goto exit; } data = kzalloc(sizeof(struct apds9130_data), GFP_KERNEL); if (!data) { err = -ENOMEM; printk("apds9130 probe failed due to no memory %d\n",err); goto exit; } data->client = client; apds9130_i2c_client = client; i2c_set_clientdata(client, data); wake_lock_init(&data->ps_wlock, WAKE_LOCK_SUSPEND, "proxi_wakelock"); data->enable = 0; /* default mode is standard */ data->ps_threshold = APDS9130_PS_DETECTION_THRESHOLD; data->ps_hysteresis_threshold = APDS9130_PS_HSYTERESIS_THRESHOLD; data->ps_detection = 0; /* default to no detection */ data->enable_ps_sensor = 0; // default to 0 #if defined(APDS9130_PROXIMITY_CAL) data->cross_talk=PS_DEFAULT_CROSS_TALK; #endif mutex_init(&data->update_lock); /* Initialize the APDS-9130 chip */ err = apds9130_init_client(client); if (err < 0){ printk("apds9130 probe failed due to init client Ret = %d\n",err); goto exit_kfree; } INIT_DELAYED_WORK(&data->dwork, apds9130_work_handler); if (request_irq(client->irq, apds9130_interrupt, IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, APDS9130_DRV_NAME, (void *)client)) { printk(KERN_INFO"%s Could not allocate APDS9130_INT %d !\n", __func__,client->irq); goto exit_kfree; } enable_irq_wake(client->irq); printk(KERN_INFO"%s interrupt is hooked\n", __func__); data->input_dev_ps = input_allocate_device(); if (!data->input_dev_ps) { err = -ENOMEM; printk(KERN_INFO"Failed to allocate input device ps\n"); goto exit_free_irq; } set_bit(EV_ABS, data->input_dev_ps->evbit); input_set_abs_params(data->input_dev_ps, ABS_DISTANCE, 0, 1, 0, 0); data->input_dev_ps->name = "proximity"; err = input_register_device(data->input_dev_ps); if (err) { err = -ENOMEM; printk(KERN_INFO"Unable to register input device ps: %s\n", data->input_dev_ps->name); goto exit_free_dev_ps; } data->sw_mode = PROX_STAT_OPERATING; /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &apds9130_attr_group); if (err) goto exit_unregister_dev_ps; printk(KERN_INFO"%s support ver. %s enabled\n", __func__, DRIVER_VERSION); return 0; // sysfs_remove_group(&client->dev.kobj, &apds9130_attr_group); //Need to disable this [email protected] exit_unregister_dev_ps: input_unregister_device(data->input_dev_ps); exit_free_dev_ps: input_free_device(data->input_dev_ps); exit_free_irq: free_irq(client->irq, client); exit_kfree: //[LGSI_SP4_BSP_BEGIN][[email protected]] 30-11-2012 Destroy the mutex after its usage wake_lock_destroy(&data->ps_wlock); mutex_destroy(&data->update_lock); //[LGSI_SP4_BSP_END][[email protected]] kfree(data); exit:
static int __devinit apds9130_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct apds9130_data *data; int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { err = -EIO; goto exit; } data = kzalloc(sizeof(struct apds9130_data), GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit; } data->client = client; apds9130_i2c_client = client; i2c_set_clientdata(client, data); data->enable = 0; /* default mode is standard */ data->ps_detection = 0; /* default to no detection */ data->enable_ps_sensor = 0; // default to 0 data->ps_poll_delay = 100; // 100ms data->add_to_cross_talk = ADD_TO_CROSS_TALK; data->sub_from_ps_threshold = SUB_FROM_PS_THRESHOLD; if(stored_cross_talk >=0 && stored_cross_talk <= 720) data->cross_talk = stored_cross_talk; else data->cross_talk = DEFAULT_CROSS_TALK; data->avg_cross_talk = stored_cross_talk; data->ps_threshold = data->cross_talk + data->add_to_cross_talk; data->ps_hysteresis_threshold = data->ps_threshold - data->sub_from_ps_threshold; printk("[ProximitySensor] %s : stored_cross_talk = %d, data->cross_talk = %d\n[ProximitySensor] %s : %d < ps_data < %d\n", __func__, stored_cross_talk, data->cross_talk, __func__, data->ps_hysteresis_threshold, data->ps_threshold); data->irq_wake = 0; mutex_init(&data->update_lock); err = gpio_request(APDS9130_INT, "apds9130_irq"); if(err) { printk("[ProximitySensor_E] %s : gpio request fail\n", __func__); goto exit_kfree; } gpio_direction_input(APDS9130_INT); data->irq = gpio_to_irq(APDS9130_INT); if (request_irq(data->irq, apds9130_interrupt, IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, APDS9130_DRV_NAME, (void *)client)) { printk("[ProximitySensor_E] %s : Could not allocate APDS9130_IRQ !\n", __func__); goto exit_kfree; } // irq_set_irq_wake(data->irq, 1); INIT_DELAYED_WORK(&data->dwork, apds9130_work_handler); INIT_DELAYED_WORK(&data->ps_dwork, apds9130_ps_polling_work_handler); /* Initialize the APDS-9130 chip */ err = apds9130_init_client(client); if (err) goto exit_kfree; data->input_dev_ps = input_allocate_device(); if (!data->input_dev_ps) { err = -ENOMEM; printk("[ProximitySensor_E] %s : Failed to allocate input device ps !\n", __func__); goto exit_free_irq; } set_bit(EV_ABS, data->input_dev_ps->evbit); input_set_abs_params(data->input_dev_ps, ABS_DISTANCE, 0, 1, 0, 0); data->input_dev_ps->name = "Avago proximity sensor"; err = input_register_device(data->input_dev_ps); if (err) { err = -ENOMEM; printk("[ProximitySensor_E] %s : Unable to register input device ps(%s)\n", __func__, data->input_dev_ps->name); goto exit_free_dev_ps; } /* Register sysfs hooks */ err = sysfs_create_group(&client->dev.kobj, &apds9130_attr_group); if (err) goto exit_unregister_dev_ps; printk("[ProximitySensor] %s : support ver. %s enabled\n", __func__, DRIVER_VERSION); wake_lock_init(&data->wakelock, WAKE_LOCK_SUSPEND, data->input_dev_ps->name); return 0; exit_unregister_dev_ps: input_unregister_device(data->input_dev_ps); exit_free_dev_ps: exit_free_irq: free_irq(data->irq, client); exit_kfree: kfree(data); exit: return err; }