static void gp2a_shutdown(struct i2c_client *client) { struct gp2a_data *data = i2c_get_clientdata(client); pr_info("%s, is called\n", __func__); bShutdown = true; if (data->light_enabled) { cancel_delayed_work_sync(&data->light_work); lightsensor_onoff(0, data); input_report_rel(data->light_input_dev, REL_MISC, data->lux + 1); input_sync(data->light_input_dev); } input_unregister_device(data->light_input_dev); input_free_device(data->light_input_dev); #ifdef CONFIG_SENSORS_GP2A030A_PROX if (data->prox_enabled) { disable_irq(data->irq); disable_irq_wake(data->irq); gp2a_prox_onoff(0, data); wake_unlock(&data->prx_wake_lock); } wake_lock_destroy(&data->prx_wake_lock); input_unregister_device(data->prox_input_dev); input_free_device(data->prox_input_dev); gpio_free(data->gpio); if (system_rev >= 12) { gpio_free(data->con_gpio); } #ifndef CONFIG_SEC_BERLUTI_PROJECT gpio_free(data->vled_gpio); #endif #endif mutex_destroy(&data->light_mutex); mutex_destroy(&data->data_mutex); kfree(data); gp2a_regulator_onoff(&client->dev, false); }
static int gp2a_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; struct input_dev *input_dev; struct gp2a_data *gp2a; struct gp2a_platform_data *pdata = client->dev.platform_data; pr_info("%s, start\n", __func__); ret = gp2a_regulator_onoff(&client->dev, true); if (ret) { pr_err("%s, Power Up Failed\n", __func__); return ret; } if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct gp2a_platform_data), GFP_KERNEL); if (!pdata) { pr_err("%s,Failed to allocate memory\n", __func__); return -ENOMEM; } ret = gp2a_parse_dt(&client->dev, pdata); if (ret < 0) return ret; ret = gp2a_request_gpio(pdata); if (ret < 0) return ret; } if (!pdata) { pr_err("%s,missing pdata\n", __func__); return -ENOMEM; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("%s,i2c functionality failed\n", __func__); return -ENOMEM; } gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!gp2a) { pr_err("%s,failed memory alloc\n", __func__); return -ENOMEM; } gp2a->pdata = pdata; gp2a->i2c_client = client; i2c_set_clientdata(client, gp2a); wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); mutex_init(&gp2a->power_lock); input_dev = input_allocate_device(); if (!input_dev) { pr_err("%s,could not allocate input device\n", __func__); goto err_input_allocate_device_proximity; } gp2a->input = input_dev; input_dev->name = "proximity_sensor"; input_set_capability(input_dev, EV_ABS, ABS_DISTANCE); input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0); input_set_drvdata(input_dev, gp2a); ret = input_register_device(input_dev); if (ret < 0) { pr_err("%s,could not register input device\n", __func__); goto err_input_register_device_proximity; } ret = sensors_create_symlink(&input_dev->dev.kobj, input_dev->name); if (ret < 0) { pr_err("%s,create sysfs symlink error\n", __func__); goto err_sysfs_create_symlink_proximity; } ret = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group); if (ret) { pr_err("%s,create sysfs group error\n", __func__); goto err_sysfs_create_group_proximity; } INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func); gp2a_leda_onoff(gp2a, 1); ret = gp2a_setup_irq(gp2a); if (ret) { pr_err("%s,could not setup irq\n", __func__); goto err_setup_irq; } gp2a_leda_onoff(gp2a, 0); ret = sensors_register(gp2a->dev, gp2a, proxi_attrs, "proximity_sensor"); if (ret < 0) { pr_info("%s,could not sensors_register\n", __func__); goto exit_gp2a_sensors_register; } pr_info("%s done\n", __func__); goto done; exit_gp2a_sensors_register: free_irq(gp2a->irq, gp2a); gpio_free(gp2a->pdata->p_out); err_setup_irq: gp2a_leda_onoff(gp2a, 0); sysfs_remove_group(&gp2a->input->dev.kobj, &proximity_attribute_group); err_sysfs_create_group_proximity: sensors_remove_symlink(&gp2a->input->dev.kobj, gp2a->input->name); err_sysfs_create_symlink_proximity: input_unregister_device(gp2a->input); err_input_register_device_proximity: input_free_device(input_dev); err_input_allocate_device_proximity: mutex_destroy(&gp2a->power_lock); wake_lock_destroy(&gp2a->prx_wake_lock); kfree(gp2a); done: gp2a_regulator_onoff(&client->dev, false); return ret; }
static ssize_t proximity_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct gp2a_data *gp2a = dev_get_drvdata(dev); int value = 0; int err = 0; err = kstrtoint(buf, 10, &value); if (err) { pr_err("%s,kstrtoint failed.", __func__); goto done; } if (value != 0 && value != 1) { pr_err("%s,wrong value(%d)\n", __func__, value); goto done; } mutex_lock(&gp2a->power_lock); if (gp2a->power_state != value) { pr_info("%s,enable(%d)\n", __func__, value); if (value) { err = gp2a_cal_mode_read_file(gp2a); if (err < 0 && err != -ENOENT) pr_err("%s,cal_mode file read fail\n", __func__); pr_info("%s,mode(%d)\n", __func__, gp2a->cal_mode); if (gp2a->cal_mode == 2) { gp2a->nondetect = PROX_NONDETECT_MODE2; gp2a->detect = PROX_DETECT_MODE2; } else if (gp2a->cal_mode == 1) { gp2a->nondetect = PROX_NONDETECT_MODE1; gp2a->detect = PROX_DETECT_MODE1; } else { gp2a->nondetect = PROX_NONDETECT; gp2a->detect = PROX_DETECT; } gp2a_regulator_onoff(&gp2a->i2c_client->dev, true); gp2a_power_onoff(gp2a, 1); gp2a->power_state = value; gp2a->val_state = value; input_report_abs(gp2a->input, ABS_DISTANCE, gp2a->val_state); input_sync(gp2a->input); } else { gp2a_power_onoff(gp2a, 0); gp2a_regulator_onoff(&gp2a->i2c_client->dev, false); gp2a->power_state = value; } } else { pr_err("%s,wrong cmd for enable\n", __func__); } mutex_unlock(&gp2a->power_lock); done: return size; }
static int gp2a_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct gp2a_data *data; u8 value; pr_info("%s, is called\n", __func__); if (client == NULL) { pr_err("%s, client doesn't exist\n", __func__); err = -ENOMEM; return err; } err = gp2a_regulator_onoff(&client->dev, true); if (err) { pr_err("%s, Power Up Failed\n", __func__); return err; } data = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL); if (!data) { pr_err("%s, kzalloc error\n", __func__); err = -ENOMEM; return err; } #ifdef CONFIG_SENSORS_GP2A030A_PROX err = gp2a_parse_dt(data, &client->dev); if (err) { pr_err("%s, get gpio is failed\n", __func__); goto gp2a_parse_dt_err; } #endif data->client = client; data->light_delay = MAX_DELAY; bShutdown = false; i2c_set_clientdata(client, data); value = 0x00; err = gp2a_i2c_write(data, (u8) (COMMAND1), &value); if (err < 0) { pr_err("%s failed : threre is no such device.\n", __func__); goto i2c_fail_err; } data->light_input_dev = input_allocate_device(); if (!data->light_input_dev) { pr_err("%s input_allocate_device error\n", __func__); err = -ENOMEM; goto input_allocate_light_device_err; } data->light_input_dev->name = "light_sensor"; input_set_capability(data->light_input_dev, EV_REL, REL_MAX); input_set_capability(data->light_input_dev, EV_REL, REL_MISC); input_set_drvdata(data->light_input_dev, data); err = input_register_device(data->light_input_dev); if (err < 0) { pr_err("%s input_register_device light error\n", __func__); goto input_register_device_err; } #if defined(CONFIG_SEC_BERLUTI_PROJECT) err = sensors_create_symlink(&data->light_input_dev->dev.kobj, data->light_input_dev->name); if (err < 0) { pr_err("%s sensors_create_symlink light error\n", __func__); goto sensors_create_symlink_err; } #endif err = sysfs_create_group(&data->light_input_dev->dev.kobj, &gp2a_light_attribute_group); if (err) { pr_err("%s sysfs_create_group light error\n", __func__); goto sysfs_create_group_light_err; } #ifdef CONFIG_SENSORS_GP2A030A_PROX err = gp2a_setup_irq(data); if (err) { pr_err("%s: could not setup irq\n", __func__); goto err_setup_irq; } data->prox_input_dev = input_allocate_device(); if (!data->prox_input_dev) { pr_err("%s input_allocate_device error\n", __func__); err = -ENOMEM; goto input_allocate_prox_device_err; } data->prox_input_dev->name = "proximity_sensor"; input_set_capability(data->prox_input_dev, EV_ABS, ABS_DISTANCE); input_set_capability(data->prox_input_dev, EV_ABS, ABS_MAX); input_set_abs_params(data->prox_input_dev, ABS_DISTANCE, 0, 1, 0, 0); input_set_abs_params(data->prox_input_dev, ABS_MAX, 0, 1, 0, 0); input_set_drvdata(data->prox_input_dev, data); err = input_register_device(data->prox_input_dev); if (err < 0) { pr_err("%s input_register_device prox error\n", __func__); goto input_register_prox_device_err; } #if defined(CONFIG_SEC_BERLUTI_PROJECT) err = sensors_create_symlink(&data->prox_input_dev->dev.kobj, data->prox_input_dev->name); if (err < 0) { pr_err("%s sensors_create_symlink light error\n", __func__); goto sensors_create_symlink_light_err; } #endif err = sysfs_create_group(&data->prox_input_dev->dev.kobj, &gp2a_prox_attribute_group); if (err) { pr_err("%s sysfs_create_group prox error\n", __func__); goto sysfs_create_group_prox_err; } #endif #ifdef CONFIG_SENSORS err = sensors_register(data->light_sensor_device, data, light_sensor_attrs, "light_sensor"); if (err) { pr_err("%s: cound not register prox sensor device(%d).\n", __func__, err); goto sensors_register_light_err; } #ifdef CONFIG_SENSORS_GP2A030A_PROX err = sensors_register(data->prox_sensor_device, data, prox_sensor_attrs, "proximity_sensor"); if (err) { pr_err("%s: cound not register prox sensor device(%d).\n", __func__, err); goto sensors_register_prox_err; } #endif #endif mutex_init(&data->light_mutex); mutex_init(&data->data_mutex); INIT_DELAYED_WORK(&data->light_work, gp2a_work_func_light); #ifdef CONFIG_SENSORS_GP2A030A_PROX wake_lock_init(&data->prx_wake_lock, WAKE_LOCK_SUSPEND, "prx_wake_lock"); INIT_WORK(&data->proximity_work, gp2a_work_func_prox); #ifdef CONFIG_SENSORS INIT_DELAYED_WORK(&data->prox_avg_work, gp2a_work_avg_prox); #endif #endif goto done; mutex_destroy(&data->light_mutex); mutex_destroy(&data->data_mutex); #ifdef CONFIG_SENSORS #ifdef CONFIG_SENSORS_GP2A030A_PROX sensors_unregister(data->prox_sensor_device, prox_sensor_attrs); sensors_register_prox_err: #endif sensors_unregister(data->light_sensor_device, light_sensor_attrs); sensors_register_light_err: #endif #ifdef CONFIG_SENSORS_GP2A030A_PROX sysfs_remove_group(&data->prox_input_dev->dev.kobj, &gp2a_prox_attribute_group); sysfs_create_group_prox_err: #if defined(CONFIG_SEC_BERLUTI_PROJECT) sensors_remove_symlink(&data->prox_input_dev->dev.kobj, data->prox_input_dev->name); sensors_create_symlink_err: #endif input_unregister_device(data->prox_input_dev); input_register_prox_device_err: input_free_device(data->prox_input_dev); input_allocate_prox_device_err: gpio_free(data->gpio); #ifndef CONFIG_SEC_BERLUTI_PROJECT gpio_free(data->vled_gpio); #endif err_setup_irq: #endif sysfs_remove_group(&data->light_input_dev->dev.kobj, &gp2a_light_attribute_group); sysfs_create_group_light_err: #if defined(CONFIG_SEC_BERLUTI_PROJECT) sensors_remove_symlink(&data->light_input_dev->dev.kobj, data->light_input_dev->name); sensors_create_symlink_light_err: #endif input_unregister_device(data->light_input_dev); input_register_device_err: input_free_device(data->light_input_dev); input_allocate_light_device_err: i2c_fail_err: #ifdef CONFIG_SENSORS_GP2A030A_PROX gp2a_parse_dt_err: #endif kfree(data); gp2a_regulator_onoff(&client->dev, false); bShutdown = true; done: return err; }