162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _SCD30_H
362306a36Sopenharmony_ci#define _SCD30_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/completion.h>
662306a36Sopenharmony_ci#include <linux/device.h>
762306a36Sopenharmony_ci#include <linux/mutex.h>
862306a36Sopenharmony_ci#include <linux/pm.h>
962306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
1062306a36Sopenharmony_ci#include <linux/types.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct scd30_state;
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cienum scd30_cmd {
1562306a36Sopenharmony_ci	/* start continuous measurement with pressure compensation */
1662306a36Sopenharmony_ci	CMD_START_MEAS,
1762306a36Sopenharmony_ci	/* stop continuous measurement */
1862306a36Sopenharmony_ci	CMD_STOP_MEAS,
1962306a36Sopenharmony_ci	/* set/get measurement interval */
2062306a36Sopenharmony_ci	CMD_MEAS_INTERVAL,
2162306a36Sopenharmony_ci	/* check whether new measurement is ready */
2262306a36Sopenharmony_ci	CMD_MEAS_READY,
2362306a36Sopenharmony_ci	/* get measurement */
2462306a36Sopenharmony_ci	CMD_READ_MEAS,
2562306a36Sopenharmony_ci	/* turn on/off automatic self calibration */
2662306a36Sopenharmony_ci	CMD_ASC,
2762306a36Sopenharmony_ci	/* set/get forced recalibration value */
2862306a36Sopenharmony_ci	CMD_FRC,
2962306a36Sopenharmony_ci	/* set/get temperature offset */
3062306a36Sopenharmony_ci	CMD_TEMP_OFFSET,
3162306a36Sopenharmony_ci	/* get firmware version */
3262306a36Sopenharmony_ci	CMD_FW_VERSION,
3362306a36Sopenharmony_ci	/* reset sensor */
3462306a36Sopenharmony_ci	CMD_RESET,
3562306a36Sopenharmony_ci	/*
3662306a36Sopenharmony_ci	 * Command for altitude compensation was omitted intentionally because
3762306a36Sopenharmony_ci	 * the same can be achieved by means of CMD_START_MEAS which takes
3862306a36Sopenharmony_ci	 * pressure above the sea level as an argument.
3962306a36Sopenharmony_ci	 */
4062306a36Sopenharmony_ci};
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#define SCD30_MEAS_COUNT 3
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_citypedef int (*scd30_command_t)(struct scd30_state *state, enum scd30_cmd cmd, u16 arg,
4562306a36Sopenharmony_ci			       void *response, int size);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct scd30_state {
4862306a36Sopenharmony_ci	/* serialize access to the device */
4962306a36Sopenharmony_ci	struct mutex lock;
5062306a36Sopenharmony_ci	struct device *dev;
5162306a36Sopenharmony_ci	struct regulator *vdd;
5262306a36Sopenharmony_ci	struct completion meas_ready;
5362306a36Sopenharmony_ci	/*
5462306a36Sopenharmony_ci	 * priv pointer is solely for serdev driver private data. We keep it
5562306a36Sopenharmony_ci	 * here because driver_data inside dev has been already used for iio and
5662306a36Sopenharmony_ci	 * struct serdev_device doesn't have one.
5762306a36Sopenharmony_ci	 */
5862306a36Sopenharmony_ci	void *priv;
5962306a36Sopenharmony_ci	int irq;
6062306a36Sopenharmony_ci	/*
6162306a36Sopenharmony_ci	 * no way to retrieve current ambient pressure compensation value from
6262306a36Sopenharmony_ci	 * the sensor so keep one around
6362306a36Sopenharmony_ci	 */
6462306a36Sopenharmony_ci	u16 pressure_comp;
6562306a36Sopenharmony_ci	u16 meas_interval;
6662306a36Sopenharmony_ci	int meas[SCD30_MEAS_COUNT];
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	scd30_command_t command;
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciextern const struct dev_pm_ops scd30_pm_ops;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciint scd30_probe(struct device *dev, int irq, const char *name, void *priv, scd30_command_t command);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#endif
76