if (on) {
ret = pm_runtime_resume_and_get(dev);
} else {
pm_runtime_mark_last_busy(dev);
ret = pm_runtime_put_autosuspend(dev);
}
return ret;
}
staticint vcnl4035_read_info_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val)
{ struct vcnl4035_data *data = iio_priv(indio_dev); int ret; int raw_data; unsignedint reg;
if (!iio_device_claim_direct(indio_dev)) return -EBUSY;
if (chan->channel)
reg = VCNL4035_ALS_DATA; else
reg = VCNL4035_WHITE_DATA;
ret = regmap_read(data->regmap, reg, &raw_data);
iio_device_release_direct(indio_dev); if (ret) return ret;
*val = raw_data;
return IIO_VAL_INT;
}
/* * Device IT INT Time (ms) Scale (lux/step) * 000 50 0.064 * 001 100 0.032 * 010 200 0.016 * 100 400 0.008 * 101 - 111 800 0.004 * Values are proportional, so ALS INT is selected for input due to * simplicity reason. Integration time value and scaling is * calculated based on device INT value * * Raw value needs to be scaled using ALS steps
*/ staticint vcnl4035_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{ struct vcnl4035_data *data = iio_priv(indio_dev); int ret;
switch (mask) { case IIO_CHAN_INFO_RAW:
ret = vcnl4035_set_pm_runtime_state(data, true); if (ret < 0) return ret;
ret = vcnl4035_read_info_raw(indio_dev, chan, val);
vcnl4035_set_pm_runtime_state(data, false); return ret; case IIO_CHAN_INFO_INT_TIME:
*val = 50; if (data->als_it_val)
*val = data->als_it_val * 100; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE:
*val = 64; if (!data->als_it_val)
*val2 = 1000; else
*val2 = data->als_it_val * 2 * 1000; return IIO_VAL_FRACTIONAL; default: return -EINVAL;
}
}
staticint vcnl4035_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask)
{ int ret; struct vcnl4035_data *data = iio_priv(indio_dev);
switch (mask) { case IIO_CHAN_INFO_INT_TIME: if (val <= 0 || val > 800) return -EINVAL;
ret = vcnl4035_set_pm_runtime_state(data, true); if (ret < 0) return ret;
ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
VCNL4035_ALS_IT_MASK,
val / 100); if (!ret)
data->als_it_val = val / 100;
/* No direct ABI for persistence and threshold, so eventing */ staticint vcnl4035_read_thresh(struct iio_dev *indio_dev, conststruct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, int *val, int *val2)
{ struct vcnl4035_data *data = iio_priv(indio_dev);
switch (info) { case IIO_EV_INFO_VALUE: switch (dir) { case IIO_EV_DIR_RISING:
*val = data->als_thresh_high; return IIO_VAL_INT; case IIO_EV_DIR_FALLING:
*val = data->als_thresh_low; return IIO_VAL_INT; default: return -EINVAL;
} break; case IIO_EV_INFO_PERIOD:
*val = data->als_persistence; return IIO_VAL_INT; default: return -EINVAL;
}
}
staticint vcnl4035_write_thresh(struct iio_dev *indio_dev, conststruct iio_chan_spec *chan, enum iio_event_type type, enum iio_event_direction dir, enum iio_event_info info, int val, int val2)
{ struct vcnl4035_data *data = iio_priv(indio_dev); int ret;
switch (info) { case IIO_EV_INFO_VALUE: /* 16 bit threshold range 0 - 65535 */ if (val < 0 || val > 65535) return -EINVAL; if (dir == IIO_EV_DIR_RISING) { if (val < data->als_thresh_low) return -EINVAL;
ret = regmap_write(data->regmap, VCNL4035_ALS_THDH,
val); if (ret) return ret;
data->als_thresh_high = val;
} else { if (val > data->als_thresh_high) return -EINVAL;
ret = regmap_write(data->regmap, VCNL4035_ALS_THDL,
val); if (ret) return ret;
data->als_thresh_low = val;
} return ret; case IIO_EV_INFO_PERIOD: /* allow only 1 2 4 8 as persistence value */ if (val < 0 || val > 8 || hweight8(val) != 1) return -EINVAL;
ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
VCNL4035_ALS_PERS_MASK, val); if (!ret)
data->als_persistence = val; return ret; default: return -EINVAL;
}
}
staticint vcnl4035_init(struct vcnl4035_data *data)
{ int ret; int id;
ret = regmap_read(data->regmap, VCNL4035_DEV_ID, &id); if (ret < 0) {
dev_err(&data->client->dev, "Failed to read DEV_ID register\n"); return ret;
}
id = FIELD_GET(VCNL4035_DEV_ID_MASK, id); if (id != VCNL4035_DEV_ID_VAL) {
dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
id, VCNL4035_DEV_ID_VAL); return -ENODEV;
}
ret = vcnl4035_set_als_power_state(data, VCNL4035_MODE_ALS_ENABLE); if (ret < 0) return ret;
/* ALS white channel enable */
ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
VCNL4035_MODE_ALS_WHITE_CHAN,
1); if (ret) {
dev_err(&data->client->dev, "set white channel enable %d\n",
ret); return ret;
}
/* set default integration time - 100 ms for ALS */
ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
VCNL4035_ALS_IT_MASK,
VCNL4035_ALS_IT_DEFAULT); if (ret) {
dev_err(&data->client->dev, "set default ALS IT returned %d\n",
ret); return ret;
}
data->als_it_val = VCNL4035_ALS_IT_DEFAULT;
/* set default persistence time - 1 for ALS */
ret = regmap_update_bits(data->regmap, VCNL4035_ALS_CONF,
VCNL4035_ALS_PERS_MASK,
VCNL4035_ALS_PERS_DEFAULT); if (ret) {
dev_err(&data->client->dev, "set default PERS returned %d\n",
ret); return ret;
}
data->als_persistence = VCNL4035_ALS_PERS_DEFAULT;
/* set default HIGH threshold for ALS */
ret = regmap_write(data->regmap, VCNL4035_ALS_THDH,
VCNL4035_ALS_THDH_DEFAULT); if (ret) {
dev_err(&data->client->dev, "set default THDH returned %d\n",
ret); return ret;
}
data->als_thresh_high = VCNL4035_ALS_THDH_DEFAULT;
/* set default LOW threshold for ALS */
ret = regmap_write(data->regmap, VCNL4035_ALS_THDL,
VCNL4035_ALS_THDL_DEFAULT); if (ret) {
dev_err(&data->client->dev, "set default THDL returned %d\n",
ret); return ret;
}
data->als_thresh_low = VCNL4035_ALS_THDL_DEFAULT;
return 0;
}
staticbool vcnl4035_is_volatile_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case VCNL4035_ALS_CONF: case VCNL4035_DEV_ID: returnfalse; default: returntrue;
}
}
ret = vcnl4035_set_als_power_state(iio_priv(indio_dev),
VCNL4035_MODE_ALS_DISABLE); if (ret)
dev_warn(&client->dev, "Failed to put device into standby (%pe)\n",
ERR_PTR(ret));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.