static ssize_t apds990x_prox_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct apds990x_chip *chip = dev_get_drvdata(dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) return -EINVAL; mutex_lock(&chip->mutex); if (!chip->prox_en) chip->prox_data = 0; if (value) chip->prox_en++; else if (chip->prox_en > 0) chip->prox_en--; if (!pm_runtime_suspended(dev)) apds990x_mode_on(chip); mutex_unlock(&chip->mutex); return len; }
static int apds990x_chip_on(struct apds990x_chip *chip) { int err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs); if (err < 0) return err; usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY); /* Refresh all configs in case of regulators were off */ chip->prox_data = 0; apds990x_configure(chip); apds990x_mode_on(chip); return 0; }
static int apds990x_chip_on(struct apds990x_chip *chip) { int err; if (chip->pdata->power_on) { err = chip->pdata->power_on(1); if (err < 0) return err; } usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY); /* Refresh all configs in case of power was off */ chip->prox_data = 0; apds990x_configure(chip); apds990x_mode_on(chip); return 0; }
static int __devinit apds990x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct apds990x_chip *chip; int err; chip = kzalloc(sizeof *chip, GFP_KERNEL); if (!chip) return -ENOMEM; i2c_set_clientdata(client, chip); chip->client = client; init_waitqueue_head(&chip->wait); mutex_init(&chip->mutex); chip->pdata = client->dev.platform_data; if (chip->pdata == NULL) { dev_err(&client->dev, "platform data is mandatory\n"); err = -EINVAL; goto fail1; } if (chip->pdata->cf.ga == 0) { /* set uncovered sensor default parameters */ chip->cf.ga = 1966; /* 0.48 * APDS_PARAM_SCALE */ chip->cf.cf1 = 4096; /* 1.00 * APDS_PARAM_SCALE */ chip->cf.irf1 = 9134; /* 2.23 * APDS_PARAM_SCALE */ chip->cf.cf2 = 2867; /* 0.70 * APDS_PARAM_SCALE */ chip->cf.irf2 = 5816; /* 1.42 * APDS_PARAM_SCALE */ chip->cf.df = 52; } else { chip->cf = chip->pdata->cf; } /* precalculate inverse chip factors for threshold control */ chip->rcf.afactor = (chip->cf.irf1 - chip->cf.irf2) * APDS_PARAM_SCALE / (chip->cf.cf1 - chip->cf.cf2); chip->rcf.cf1 = APDS_PARAM_SCALE * APDS_PARAM_SCALE / chip->cf.cf1; chip->rcf.irf1 = chip->cf.irf1 * APDS_PARAM_SCALE / chip->cf.cf1; chip->rcf.cf2 = APDS_PARAM_SCALE * APDS_PARAM_SCALE / chip->cf.cf2; chip->rcf.irf2 = chip->cf.irf2 * APDS_PARAM_SCALE / chip->cf.cf2; /* Set something to start with */ chip->lux_thres_hi = APDS_LUX_DEF_THRES_HI; chip->lux_thres_lo = APDS_LUX_DEF_THRES_LO; chip->lux_calib = APDS_LUX_NEUTRAL_CALIB_VALUE; chip->prox_thres = APDS_PROX_DEF_THRES; chip->pdrive = chip->pdata->pdrive; chip->pdiode = APDS_PDIODE_IR; chip->pgain = APDS_PGAIN_1X; chip->prox_calib = APDS_PROX_NEUTRAL_CALIB_VALUE; chip->prox_persistence = APDS_DEFAULT_PROX_PERS; chip->prox_continuous_mode = false; chip->regs[0].supply = reg_vcc; chip->regs[1].supply = reg_vled; err = regulator_bulk_get(&client->dev, ARRAY_SIZE(chip->regs), chip->regs); if (err < 0) { dev_err(&client->dev, "Cannot get regulators\n"); goto fail1; } err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs); if (err < 0) { dev_err(&client->dev, "Cannot enable regulators\n"); goto fail2; } usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY); err = apds990x_detect(chip); if (err < 0) { dev_err(&client->dev, "APDS990X not found\n"); goto fail3; } pm_runtime_set_active(&client->dev); apds990x_configure(chip); apds990x_set_arate(chip, APDS_LUX_DEFAULT_RATE); apds990x_mode_on(chip); pm_runtime_enable(&client->dev); if (chip->pdata->setup_resources) { err = chip->pdata->setup_resources(); if (err) { err = -EINVAL; goto fail3; } } err = sysfs_create_group(&chip->client->dev.kobj, apds990x_attribute_group); if (err < 0) { dev_err(&chip->client->dev, "Sysfs registration failed\n"); goto fail4; } err = request_threaded_irq(client->irq, NULL, apds990x_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW | IRQF_ONESHOT, "apds990x", chip); if (err) { dev_err(&client->dev, "could not get IRQ %d\n", client->irq); goto fail5; } return err; fail5: sysfs_remove_group(&chip->client->dev.kobj, &apds990x_attribute_group[0]); fail4: if (chip->pdata && chip->pdata->release_resources) chip->pdata->release_resources(); fail3: regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs); fail2: regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs); fail1: kfree(chip); return err; }