static ssize_t light_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cm3663_data *cm3663 = dev_get_drvdata(dev); bool new_value; if (sysfs_streq(buf, "1")) new_value = true; else if (sysfs_streq(buf, "0")) new_value = false; else { pr_err("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } mutex_lock(&cm3663->power_lock); if (new_value && !(cm3663->power_state & LIGHT_ENABLED)) { cm3663->power_state |= LIGHT_ENABLED; cm3663_light_enable(cm3663); } else if (!new_value && (cm3663->power_state & LIGHT_ENABLED)) { cm3663_light_disable(cm3663); cm3663->power_state &= ~LIGHT_ENABLED; } mutex_unlock(&cm3663->power_lock); return size; }
static int cm3663_i2c_remove(struct i2c_client *client) { struct cm3663_data *cm3663 = i2c_get_clientdata(client); device_remove_file(cm3663->switch_cmd_dev, &dev_attr_adc); device_remove_file(cm3663->proximity_dev, &dev_attr_prox_cal); device_remove_file(cm3663->proximity_dev, &dev_attr_prox_avg); device_remove_file(cm3663->proximity_dev, &dev_attr_state); device_destroy(sensors_class, 0); sysfs_remove_group(&cm3663->light_input_dev->dev.kobj, &light_attribute_group); input_unregister_device(cm3663->light_input_dev); sysfs_remove_group(&cm3663->proximity_input_dev->dev.kobj, &proximity_attribute_group); input_unregister_device(cm3663->proximity_input_dev); free_irq(cm3663->irq, NULL); if (cm3663->power_state) { if (cm3663->power_state & LIGHT_ENABLED) cm3663_light_disable(cm3663); if (cm3663->power_state & PROXIMITY_ENABLED) { cm3663_i2c_write(cm3663, REGS_PS_CMD, 0x01); cm3663->pdata->proximity_power(0); } } destroy_workqueue(cm3663->light_wq); destroy_workqueue(cm3663->prox_wq); mutex_destroy(&cm3663->power_lock); wake_lock_destroy(&cm3663->prx_wake_lock); kfree(cm3663); return 0; }
static ssize_t poll_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cm3663_data *cm3663 = dev_get_drvdata(dev); int64_t new_delay; int err; err = strict_strtoll(buf, 10, &new_delay); if (err < 0) return err; printk(KERN_INFO "[CM3663] poll_delay_store : new_delay=%lld\n", new_delay); mutex_lock(&cm3663->power_lock); if (new_delay != ktime_to_ns(cm3663->light_poll_delay)) { cm3663->light_poll_delay = ns_to_ktime(new_delay); if (cm3663->power_state & LIGHT_ENABLED) { cm3663_light_disable(cm3663); cm3663_light_enable(cm3663); } } mutex_unlock(&cm3663->power_lock); return size; }
/* * sysfs interface * Turn on or off the light sensor */ static ssize_t cm3663_light_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct cm3663_data *cm3663 = dev_get_drvdata(dev); int enable; if (strict_strtoul(buf, 10, &enable)) return -EINVAL; int enabled = cm3663->power_state & LIGHT_ENABLED; if (enable == enabled) return size; mutex_lock(&cm3663->power_lock); if (enable) { if (!(cm3663->power_state)) { pr_info("\n light_power true\n"); cm3663->pdata->proximity_power(true); } cm3663->power_state |= LIGHT_ENABLED; cm3663_light_enable(cm3663); if (!((cm3663->power_state)&PROXIMITY_ENABLED)) cm3663_i2c_write(cm3663, REGS_PS_CMD, 0x01); } else { cm3663_light_disable(cm3663); cm3663->power_state &= ~LIGHT_ENABLED; if (!((cm3663->power_state)&PROXIMITY_ENABLED)) pr_info("\n light_power false\n"); } mutex_unlock(&cm3663->power_lock); return size; }
static int cm3663_suspend(struct device *dev) { /* We disable power only if proximity is disabled. If proximity is enabled, we leave power on because proximity is allowed to wake up device. We remove power without changing cm3663->power_state because we use that state in resume. */ struct i2c_client *client = to_i2c_client(dev); struct cm3663_data *cm3663 = i2c_get_clientdata(client); if (cm3663->power_state & LIGHT_ENABLED) cm3663_light_disable(cm3663); return 0; }
static ssize_t lightsensor_file_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cm3663_data *cm3663 = dev_get_drvdata(dev); int adc = 0; if (!(cm3663->power_state & LIGHT_ENABLED)) cm3663_light_enable(cm3663); adc = lightsensor_get_alsvalue(cm3663); if (!(cm3663->power_state & LIGHT_ENABLED)) cm3663_light_disable(cm3663); return sprintf(buf, "%d\n", adc); }