Lines Matching +full:co2 +full:- +full:sensor

1 // SPDX-License-Identifier: GPL-2.0-only
3 * ccs811.c - Support for AMS CCS811 VOC Sensor
7 * Datasheet: ams.com/content/download/951091/2269479/CCS811_DS000459_3-00.pdf
48 * Value of FW_MODE bit of STATUS register describes the sensor's state:
67 __be16 co2; member
93 .scan_index = -1,
98 .scan_index = -1,
130 * The CCS811 powers-up in boot mode. A setup write to CCS811_APP_START will
131 * transition the sensor to application mode.
146 return -EIO; in ccs811_start_sensor_application()
158 dev_err(&client->dev, "Application failed to start. Sensor is still in boot mode.\n"); in ccs811_start_sensor_application()
159 return -EIO; in ccs811_start_sensor_application()
179 if (!data->wakeup_gpio) in ccs811_set_wakeup()
182 gpiod_set_value(data->wakeup_gpio, enable); in ccs811_set_wakeup()
197 while (tries-- > 0) { in ccs811_get_measurement()
198 ret = i2c_smbus_read_byte_data(data->client, CCS811_STATUS); in ccs811_get_measurement()
207 return -EIO; in ccs811_get_measurement()
209 ret = i2c_smbus_read_i2c_block_data(data->client, in ccs811_get_measurement()
211 (char *)&data->buffer); in ccs811_get_measurement()
229 mutex_lock(&data->lock); in ccs811_read_raw()
232 mutex_unlock(&data->lock); in ccs811_read_raw()
237 switch (chan->type) { in ccs811_read_raw()
239 *val = be16_to_cpu(data->buffer.raw_data) & in ccs811_read_raw()
244 *val = be16_to_cpu(data->buffer.raw_data) >> 10; in ccs811_read_raw()
248 switch (chan->channel2) { in ccs811_read_raw()
250 *val = be16_to_cpu(data->buffer.co2); in ccs811_read_raw()
254 *val = be16_to_cpu(data->buffer.voc); in ccs811_read_raw()
258 ret = -EINVAL; in ccs811_read_raw()
262 ret = -EINVAL; in ccs811_read_raw()
264 mutex_unlock(&data->lock); in ccs811_read_raw()
270 switch (chan->type) { in ccs811_read_raw()
280 switch (chan->channel2) { in ccs811_read_raw()
290 return -EINVAL; in ccs811_read_raw()
293 return -EINVAL; in ccs811_read_raw()
296 return -EINVAL; in ccs811_read_raw()
311 ret = i2c_smbus_read_byte_data(data->client, CCS811_MEAS_MODE); in ccs811_set_trigger_state()
320 data->drdy_trig_on = state; in ccs811_set_trigger_state()
322 return i2c_smbus_write_byte_data(data->client, CCS811_MEAS_MODE, ret); in ccs811_set_trigger_state()
332 struct iio_dev *indio_dev = pf->indio_dev; in ccs811_trigger_handler()
334 struct i2c_client *client = data->client; in ccs811_trigger_handler()
338 sizeof(data->scan.channels), in ccs811_trigger_handler()
339 (u8 *)data->scan.channels); in ccs811_trigger_handler()
341 dev_err(&client->dev, "cannot read sensor data\n"); in ccs811_trigger_handler()
345 iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, in ccs811_trigger_handler()
349 iio_trigger_notify_done(indio_dev->trig); in ccs811_trigger_handler()
359 if (data->drdy_trig_on) in ccs811_data_rdy_trigger_poll()
360 iio_trigger_poll(data->drdy_trig); in ccs811_data_rdy_trigger_poll()
370 reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", in ccs811_reset()
393 dev_err(&client->dev, "Failed to reset sensor\n"); in ccs811_reset()
411 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE in ccs811_probe()
414 return -EOPNOTSUPP; in ccs811_probe()
416 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); in ccs811_probe()
418 return -ENOMEM; in ccs811_probe()
422 data->client = client; in ccs811_probe()
424 data->wakeup_gpio = devm_gpiod_get_optional(&client->dev, "wakeup", in ccs811_probe()
426 if (IS_ERR(data->wakeup_gpio)) in ccs811_probe()
427 return PTR_ERR(data->wakeup_gpio); in ccs811_probe()
445 dev_err(&client->dev, "hardware id doesn't match CCS81x\n"); in ccs811_probe()
447 return -ENODEV; in ccs811_probe()
457 dev_err(&client->dev, "no CCS811 sensor\n"); in ccs811_probe()
459 return -ENODEV; in ccs811_probe()
470 mutex_init(&data->lock); in ccs811_probe()
472 indio_dev->name = id->name; in ccs811_probe()
473 indio_dev->info = &ccs811_info; in ccs811_probe()
474 indio_dev->modes = INDIO_DIRECT_MODE; in ccs811_probe()
476 indio_dev->channels = ccs811_channels; in ccs811_probe()
477 indio_dev->num_channels = ARRAY_SIZE(ccs811_channels); in ccs811_probe()
479 if (client->irq > 0) { in ccs811_probe()
480 ret = devm_request_threaded_irq(&client->dev, client->irq, in ccs811_probe()
487 dev_err(&client->dev, "irq request error %d\n", -ret); in ccs811_probe()
491 data->drdy_trig = devm_iio_trigger_alloc(&client->dev, in ccs811_probe()
492 "%s-dev%d", in ccs811_probe()
493 indio_dev->name, in ccs811_probe()
494 indio_dev->id); in ccs811_probe()
495 if (!data->drdy_trig) { in ccs811_probe()
496 ret = -ENOMEM; in ccs811_probe()
500 data->drdy_trig->dev.parent = &client->dev; in ccs811_probe()
501 data->drdy_trig->ops = &ccs811_trigger_ops; in ccs811_probe()
502 iio_trigger_set_drvdata(data->drdy_trig, indio_dev); in ccs811_probe()
503 indio_dev->trig = data->drdy_trig; in ccs811_probe()
504 iio_trigger_get(indio_dev->trig); in ccs811_probe()
505 ret = iio_trigger_register(data->drdy_trig); in ccs811_probe()
514 dev_err(&client->dev, "triggered buffer setup failed\n"); in ccs811_probe()
520 dev_err(&client->dev, "unable to register iio device\n"); in ccs811_probe()
528 if (data->drdy_trig) in ccs811_probe()
529 iio_trigger_unregister(data->drdy_trig); in ccs811_probe()
543 if (data->drdy_trig) in ccs811_remove()
544 iio_trigger_unregister(data->drdy_trig); in ccs811_remove()
574 MODULE_DESCRIPTION("CCS811 volatile organic compounds sensor");