#define DT_DRV_COMPAT sensirion_sps30

#include <kernel.h>
#include <drivers/sensor.h>
#include <init.h>
#include <sys/__assert.h>
#include <sys/byteorder.h>
#include <logging/log.h>

#include <sensor/sps30.h>

LOG_MODULE_REGISTER(sps30, CONFIG_SPS30_LOG_LEVEL);
ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
#define SPS_CMD_START_MEASUREMENT 0x0010
//#define SPS_CMD_START_MEASUREMENT_ARG 0x0300
#define SPS_CMD_START_MEASUREMENT_ARG 0x0500
#define SPS_CMD_STOP_MEASUREMENT 0x0104
#define SPS_CMD_READ_MEASUREMENT 0x0300
#define SPS_CMD_START_STOP_DELAY_USEC 20000
#define SPS_CMD_GET_DATA_READY 0x0202
#define SPS_CMD_AUTOCLEAN_INTERVAL 0x8004
#define SPS_CMD_GET_FIRMWARE_VERSION 0xd100
#define SPS_CMD_GET_SERIAL 0xd033
#define SPS_CMD_RESET 0xd304
#define SPS_CMD_SLEEP 0x1001
#define SPS_CMD_READ_DEVICE_STATUS_REG 0xd206
#define SPS_CMD_START_MANUAL_FAN_CLEANING 0x5607
#define SPS_CMD_WAKE_UP 0x1103
#define SPS_CMD_DELAY_USEC 5000
#define SPS_CMD_DELAY_WRITE_FLASH_USEC 20000
#define SPS30_CMD_STATUS 0xD206

#define STATUS_FAN_MASK    (uint8_t)0x10
#define STATUS_LASER_MASK  (uint8_t)0x20
#define STATUS_SPEED_MASK  (uint8_t)0x20

#define SPS30_SERIAL_NUM_WORDS ((SPS30_MAX_SERIAL_LEN) / 2)

#define CRC8_POLYNOMIAL 0x31
#define CRC8_INIT 0xFF
#define CRC8_LEN 1

#define SENSIRION_COMMAND_SIZE 2
#define SENSIRION_WORD_SIZE 2
#define SENSIRION_NUM_WORDS(x) (sizeof(x) / SENSIRION_WORD_SIZE)
#define SENSIRION_MAX_BUFFER_WORDS 32

#define SPS30_FAN_MAX_STABILIZATION_TIME_S_DEFAULT  60

#define NO_ERROR 0
/* deprecated defines, use NO_ERROR or custom error codes instead */
#define STATUS_OK 0
#define STATUS_FAIL (-1)

struct sps30_data {
	const struct device *i2c;
	uint8_t i2c_addr;
    uint32_t mc_1p0;
    uint32_t mc_2p5;
    uint32_t mc_4p0;
    uint32_t mc_10p0;
    uint32_t nc_0p5;
    uint32_t nc_1p0;
    uint32_t nc_2p5;
    uint32_t nc_4p0;
    uint32_t nc_10p0;
    uint32_t typical_particle_size;
	uint8_t fw_minor;
	uint8_t fw_major;
    uint8_t fan_fail;
    uint8_t speed_fail;
    uint8_t laser_fail;
	char serial_number[SPS30_MAX_SERIAL_LEN];
};

struct sps30_config {
	const struct device *bus;
	const struct sps30_bus_io *bus_io;
        const union sps30_bus_config bus_config;
};

static inline struct sps30_data *to_data(const struct device *dev)
{
	return dev->data;
}

static inline const struct sps30_config *to_config(const struct device *dev)
{
	return dev->config;
}

static inline const struct device *to_bus(const struct device *dev)
{
	return to_config(dev)->bus;
}

static inline const union sps30_bus_config* to_bus_config(const struct device *dev)
{
	return &to_config(dev)->bus_config;
}

static inline int sps30_bus_check(const struct device *dev)
{
	return to_config(dev)->bus_io->check(to_bus(dev), to_bus_config(dev));
}

static inline int sps30_reg_read(const struct device *dev,
				  uint8_t start, uint8_t *buf, int size)
{
	return to_config(dev)->bus_io->read(to_bus(dev), to_bus_config(dev),
					    buf, size);
}

static inline int sps30_reg_write(const struct device *dev, uint8_t reg,
				   uint8_t val)
{
	return to_config(dev)->bus_io->write(to_bus(dev), to_bus_config(dev),
					     &reg, val);
}

static uint16_t raw_data[10];
static uint32_t sps30_measurement_duration_time_us = SPS30_MEASUREMENT_DURATION_USEC;
static uint32_t sps30_measurement_samples_num = SPS30_MEASUREMENT_SAMPLES_NUM_DEFAULT;
static uint16_t sps30_fan_speed_stable_timeout_s = SPS30_FAN_MAX_STABILIZATION_TIME_S_DEFAULT;
static uint16_t fan_last_stabilizing_time_s = 0;
static int sps30_read_status_register(const struct device *dev);

static uint8_t sensirion_common_generate_crc(const uint8_t* data, uint16_t count) {
    uint16_t current_byte;
    uint8_t crc = CRC8_INIT;
    uint8_t crc_bit;

    /* calculates 8-Bit checksum with given polynomial */
    for (current_byte = 0; current_byte < count; ++current_byte) {
        crc ^= (data[current_byte]);
        for (crc_bit = 8; crc_bit > 0; --crc_bit) {
            if (crc & 0x80)
                crc = (crc << 1) ^ CRC8_POLYNOMIAL;
            else
                crc = (crc << 1);
        }
    }
    return crc;
}

static int8_t sensirion_common_check_crc(const uint8_t* data, uint16_t count,
                                  uint8_t checksum) {
    if (sensirion_common_generate_crc(data, count) != checksum)
        return STATUS_FAIL;
    return NO_ERROR;
}

/*
static int16_t sensirion_i2c_general_call_reset(void) {
    const uint8_t data = 0x06;
    return sensirion_i2c_write(0, &data, (uint16_t)sizeof(data));
}
*/

static uint16_t sensirion_fill_cmd_send_buf(uint8_t* buf, uint16_t cmd,
                                     const uint16_t* args, uint8_t num_args) {
    uint8_t crc;
    uint8_t i;
    uint16_t idx = 0;

    buf[idx++] = (uint8_t)((cmd & 0xFF00) >> 8);
    buf[idx++] = (uint8_t)((cmd & 0x00FF) >> 0);

    for (i = 0; i < num_args; ++i) {
        buf[idx++] = (uint8_t)((args[i] & 0xFF00) >> 8);
        buf[idx++] = (uint8_t)((args[i] & 0x00FF) >> 0);

        crc = sensirion_common_generate_crc((uint8_t*)&buf[idx - 2],
                                            SENSIRION_WORD_SIZE);
        buf[idx++] = crc;
    }
    return idx;
}

static int16_t sensirion_i2c_read_words_as_bytes(const struct device *dev, uint8_t* data,
                                          uint16_t num_words) {
    int16_t ret;
    uint16_t i, j;
    uint16_t size = num_words * (SENSIRION_WORD_SIZE + CRC8_LEN);
    uint16_t word_buf[SENSIRION_MAX_BUFFER_WORDS];
    uint8_t* const buf8 = (uint8_t*)word_buf;
	
    const struct sps30_config *cfg = to_config(dev);

    ret = cfg->bus_io->read (to_bus(dev), to_bus_config(dev), buf8, size);

    if (ret != NO_ERROR)
        return ret;

    /* check the CRC for each word */
    for (i = 0, j = 0; i < size; i += SENSIRION_WORD_SIZE + CRC8_LEN) {

        ret = sensirion_common_check_crc(&buf8[i], SENSIRION_WORD_SIZE,
                                         buf8[i + SENSIRION_WORD_SIZE]);
        if (ret != NO_ERROR)
            return ret;

        data[j++] = buf8[i];
        data[j++] = buf8[i+1];
    }

    return NO_ERROR;
}

static int16_t sensirion_i2c_read_words(const struct device *dev, uint16_t* data_words,
                                 uint16_t num_words) {
    int16_t ret;
    uint8_t i,j;
    uint8_t word_bytes[num_words * SENSIRION_WORD_SIZE];
  
    ret = sensirion_i2c_read_words_as_bytes(dev, word_bytes,
                                            num_words);
    if (ret != NO_ERROR)
        return ret;

    for (i = 0,j=0; i < (num_words * SENSIRION_WORD_SIZE); i+=2) {
        data_words[j] = ((uint16_t)word_bytes[i] << 8) | word_bytes[i+1];
        j++;
    }

    return NO_ERROR;
}

static int sensirion_i2c_write_cmd(const struct device *dev, uint16_t command) {
    uint8_t buf[SENSIRION_COMMAND_SIZE];
    uint16_t buf_size;
    const struct sps30_config *cfg = to_config(dev);

    buf_size = sensirion_fill_cmd_send_buf(buf, command, NULL, 0);

    return cfg->bus_io->write(to_bus(dev), to_bus_config(dev), buf, buf_size );
}

static int sensirion_i2c_write_cmd_with_args(const struct device *dev, uint16_t command,
                                          const uint16_t* data_words,
                                          uint16_t num_words) {
    uint8_t buf[SENSIRION_MAX_BUFFER_WORDS];
    uint16_t buf_size;
    const struct sps30_config *cfg = to_config(dev);

    buf_size = sensirion_fill_cmd_send_buf(buf, command, data_words, num_words);
    return cfg->bus_io->write(to_bus(dev), to_bus_config(dev), buf, buf_size);
}

static int16_t sensirion_i2c_delayed_read_cmd(const struct device *dev, uint16_t cmd,
                                       uint32_t delay_us, uint16_t* data_words,
                                       uint16_t num_words) {
    int16_t ret;
    uint8_t buf[SENSIRION_COMMAND_SIZE];
    const struct sps30_config *cfg = to_config(dev);

    sensirion_fill_cmd_send_buf(buf, cmd, NULL, 0);
    ret = cfg->bus_io->write(to_bus(dev), to_bus_config(dev), buf, SENSIRION_COMMAND_SIZE);
    if (ret != NO_ERROR)
        return ret;

    if (delay_us)
        k_usleep(delay_us);

    return sensirion_i2c_read_words(dev, data_words, num_words);
}

static int16_t sensirion_i2c_read_cmd(const struct device *dev, uint16_t cmd,
                               uint16_t* data_words, uint16_t num_words) {
    
    return sensirion_i2c_delayed_read_cmd(dev, cmd, 0, data_words,
                                          num_words);
}

static uint32_t sensirion_bytes_to_uint32_t(uint8_t* bytes)
{
    return (uint32_t)((uint32_t)bytes[0] << 24 | (uint32_t)bytes[1] << 16 |
           (uint32_t)bytes[2] << 8 | (uint32_t)bytes[3]); 
}
/*
static int sps30_sleep(const struct device *dev)
{
    int ret;
    ret = sensirion_i2c_write_cmd(dev, SPS_CMD_SLEEP);
    if (ret){
        return ret;
    }else{
        k_usleep(SPS_CMD_DELAY_USEC);
    }
    
    return ret;
}
*/
int16_t sps30_reset(const struct device *dev)
{
    int ret;

    ret = sensirion_i2c_write_cmd(dev, SPS_CMD_RESET);
    
    if (ret)
        return ret;

    k_usleep(SPS_CMD_DELAY_USEC);
    return ret;
}

static int16_t sps30_check_fan(const struct device *dev)
{
    int16_t ret;
    uint16_t raw_data_16[2];

    ret = sensirion_i2c_read_cmd(   dev, 
                                    SPS30_CMD_STATUS, 
                                    raw_data_16,
                                    (sizeof(raw_data_16)/sizeof(raw_data_16[0]))
                                );

    if (ret == 0){
        ret = (raw_data_16[0] & STATUS_SPEED_MASK) ? 1:0;
    }

    return ret;
}

static int sps30_read_status_register(const struct device *dev)
{
    int16_t ret;
    struct sps30_data *data = to_data(dev);
    uint16_t raw_data_16[2];

    ret = sensirion_i2c_read_cmd(   dev, 
                                    SPS30_CMD_STATUS, 
                                    raw_data_16,
                                    (sizeof(raw_data_16)/sizeof(raw_data_16[0]))
                                );

    if (ret)
        return ret;

    data->fan_fail =      (raw_data_16[1] & STATUS_FAN_MASK) ? 1:0;
    data->laser_fail =    (raw_data_16[1] & STATUS_LASER_MASK) ? 1:0;
    data->speed_fail =    (raw_data_16[0] & STATUS_SPEED_MASK) ? 1:0;
    
    return ret;
}

static int16_t sps30_read_measurement(const struct device *dev) {
    
    int16_t error;
    struct sps30_data *data = to_data(dev);

    LOG_DBG("Read SPS30 measurement: Start\n");
    for(uint8_t i = 0; i < sps30_measurement_samples_num; i++){
        error = sensirion_i2c_read_cmd(dev, SPS_CMD_READ_MEASUREMENT,raw_data, sizeof(raw_data)/sizeof(raw_data[0]));
    
        LOG_DBG("Read SPS30 measurement: Done!!! Error: %d\n",error);

        if (error) {    
            data->mc_1p0                  = 0;
            data->mc_2p5                  = 0;
            data->mc_4p0                  = 0;
            data->mc_10p0                 = 0;
            data->nc_0p5                  = 0;
            data->nc_1p0                  = 0;
            data->nc_2p5                  = 0;
            data->nc_4p0                  = 0;
            data->nc_10p0                 = 0;
            data->typical_particle_size   = 0;
            return error;
        } else {
            data->mc_1p0                  += raw_data[0];
            data->mc_2p5                  += raw_data[1];
            data->mc_4p0                  += raw_data[2];
            data->mc_10p0                 += raw_data[3];
            data->nc_0p5                  += raw_data[4];
            data->nc_1p0                  += raw_data[5];
            data->nc_2p5                  += raw_data[6];
            data->nc_4p0                  += raw_data[7];
            data->nc_10p0                 += raw_data[8];
            data->typical_particle_size   += raw_data[9];
        }

        if( i < (sps30_measurement_samples_num -1)){ /* save 1s at last cycle -> go to stop measure */
            k_usleep(1000000); /* 1s - don0t change this value */
        }
    }

    data->mc_1p0                  /= (uint32_t) sps30_measurement_samples_num;
    data->mc_2p5                  /= (uint32_t) sps30_measurement_samples_num;
    data->mc_4p0                  /= (uint32_t) sps30_measurement_samples_num;
    data->mc_10p0                 /= (uint32_t) sps30_measurement_samples_num;
    data->nc_0p5                  /= (uint32_t) sps30_measurement_samples_num;
    data->nc_1p0                  /= (uint32_t) sps30_measurement_samples_num;
    data->nc_2p5                  /= (uint32_t) sps30_measurement_samples_num;
    data->nc_4p0                  /= (uint32_t) sps30_measurement_samples_num;
    data->nc_10p0                 /= (uint32_t) sps30_measurement_samples_num;
    data->typical_particle_size   /= (uint32_t) sps30_measurement_samples_num;

    return 0;
}

static int16_t sps30_get_fan_auto_cleaning_interval(const struct device *dev, uint32_t* interval_seconds) {
    
    uint8_t data[4];
    int16_t error;

    error = sensirion_i2c_write_cmd(dev, SPS_CMD_AUTOCLEAN_INTERVAL);
    if (error != NO_ERROR) {
        return error;
    }

    k_usleep(SPS_CMD_DELAY_USEC);

    error = sensirion_i2c_read_words_as_bytes(dev, data, SENSIRION_NUM_WORDS(data));
    if (error != NO_ERROR) {
        return error;
    }

    *interval_seconds = sensirion_bytes_to_uint32_t(data);

    return 0;
}

static int16_t sps30_set_fan_auto_cleaning_interval(const struct device *dev, uint32_t interval_seconds) {
    
    int16_t ret;
    const uint16_t data[] = {(uint16_t)((interval_seconds & 0xFFFF0000) >> 16),
                             (uint16_t)(interval_seconds & 0x0000FFFF)};

    ret = sensirion_i2c_write_cmd_with_args(dev,
                                            SPS_CMD_AUTOCLEAN_INTERVAL, data,
                                            SENSIRION_NUM_WORDS(data));
    k_usleep(SPS_CMD_DELAY_WRITE_FLASH_USEC);
    return ret;
}

static int sps30_start_measurement(const struct device *dev) {
    
    const uint16_t arg = SPS_CMD_START_MEASUREMENT_ARG;
    int ret = sensirion_i2c_write_cmd_with_args(dev,
                                                    SPS_CMD_START_MEASUREMENT, &arg,
                                                    SENSIRION_NUM_WORDS(arg));

    k_usleep(SPS_CMD_START_STOP_DELAY_USEC);

    return ret;
}

static int sps30_stop_measurement(const struct device *dev) {
    
    int ret = sensirion_i2c_write_cmd(dev, SPS_CMD_STOP_MEASUREMENT);
    k_usleep(SPS_CMD_START_STOP_DELAY_USEC);

    return ret;
}

static int16_t sps30_start_manual_fan_cleaning(const struct device *dev, uint32_t ms)
{ 
    int ret;
    ret = sps30_start_measurement(dev);

    if (ret) {
        LOG_ERR("error starting measurement mode\n");
        return ret;
    }
    
    ret = sensirion_i2c_write_cmd(dev, SPS_CMD_START_MANUAL_FAN_CLEANING);
    
    if (ret)
        return ret;
    LOG_DBG("Fan cleaning start\n");
    k_msleep(ms);
    LOG_DBG("Fan cleaning end\n");

    ret = sps30_stop_measurement(dev);

    if (ret < 0)
        LOG_ERR("error stopping measuremen modet\n");
    
    
    return ret;
}

static int sps30_sample_fetch(const struct device *dev, enum sensor_channel chan)
{
    int ret;

    if (chan != SENSOR_CHAN_ALL) {
            return -ENOTSUP;
    }

    ret = sps30_reset(dev);
    if (ret != 0) {
		LOG_ERR("error reset\n");
        return ret;
    }

     k_usleep(1000000);

    ret = sps30_set_fan_auto_cleaning_interval(dev,0);
    if (ret != 0) {
		LOG_ERR("error disaling auto cleaning interval, Error: %d",ret);
        return ret;
    }

    ret = sps30_start_measurement(dev);
    if (ret) {
        LOG_ERR("error starting measurement\n");
        return ret;
    }
    
    k_usleep(sps30_measurement_duration_time_us);
    fan_last_stabilizing_time_s = sps30_fan_speed_stable_timeout_s;
    int16_t fan_status = -1;

    while(fan_last_stabilizing_time_s){
        
        fan_status = sps30_check_fan(dev);
        
        if(!fan_status){
            break;
        }

        k_usleep(1000000);
        fan_last_stabilizing_time_s--;
    }

    fan_last_stabilizing_time_s = (sps30_fan_speed_stable_timeout_s - fan_last_stabilizing_time_s);

    LOG_WRN("SPS30 Fan Stabilization time: [%ds] (fan status at the end of startup+stabilization time: [%d]", fan_last_stabilizing_time_s, fan_status );

    ret = sps30_read_measurement(dev);
    if (ret < 0)
      LOG_ERR("error reading measurement\n");

    ret = sps30_read_status_register(dev);
    if (ret < 0){
        LOG_ERR("error reading status register: error %d\n",ret);
        return ret;
    }

    ret = sps30_stop_measurement(dev);
    if (ret < 0)
        LOG_ERR("error stopping measurement\n");
    else
    	LOG_DBG("Measurement mode STOPPED\n");
    
   
    return ret;
}


static int sps30_channel_get(const struct device *dev, enum sensor_channel chan,
			      struct sensor_value *val)
{
    struct sps30_data *drv_dev = to_data(dev);

    if (chan == SENSOR_CHAN_PM_2_5) {
            val->val1 =  drv_dev->mc_2p5;
    } else if (chan == SENSOR_CHAN_PM_4) {
            val->val1 =  drv_dev->mc_4p0;
    } else if (chan == SENSOR_CHAN_PM_10) {
            val->val1 =  drv_dev->mc_10p0;
    } else if (chan == SENSOR_CHAN_PM_1_0) {
            val->val1 =  drv_dev->mc_1p0;
    } else if (chan == SENSOR_CHAN_PM_FAN_STATUS) {
            val->val1 =  drv_dev->fan_fail;
    } else if (chan == SENSOR_CHAN_PM_SPEED_STATUS) {
            val->val1 =  drv_dev->speed_fail;
    } else if (chan == SENSOR_CHAN_PM_LASER_STATUS) {
            val->val1 =  drv_dev->laser_fail;
    } else if (chan == SENSOR_CHAN_PM_FAN_STABILIZATION_TIME) {
            val->val1 = fan_last_stabilizing_time_s;
    }
    else {
            return -ENOTSUP;
    }

    return 0;
}

static int sps30_attr_set(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr, const struct sensor_value *val)
{
    
    if (attr == SENSOR_ATTR_AIR_QUALITY_FAN_CLEAN_INTERVAL) {
            sps30_set_fan_auto_cleaning_interval(dev, val->val1);
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S) {
            sps30_measurement_duration_time_us = (uint32_t)(val->val1 * SPS30_MEASUREMENT_DURATION_USEC);
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MANUAL_CLEAN) {
            sps30_start_manual_fan_cleaning(dev, val->val1);
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES) {
            sps30_measurement_samples_num = (uint32_t)(val->val1);
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MAX_FAN_STABILIZATION_TIME) {
            sps30_fan_speed_stable_timeout_s = (uint32_t)(val->val1);
    } else {
            return -ENOTSUP;
    }

    return 0;
}


static int sps30_attr_get(const struct device *dev, enum sensor_channel chan,
			   enum sensor_attribute attr, struct sensor_value *val)
{

    if (attr == SENSOR_ATTR_AIR_QUALITY_FAN_CLEAN_INTERVAL) {
            sps30_get_fan_auto_cleaning_interval(dev,&(val->val1));
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_DURATION_TIME_S) {
            val->val1 = (uint32_t)(sps30_measurement_duration_time_us / SPS30_MEASUREMENT_DURATION_USEC);
    } else if (attr == SENSOR_ATTR_AIR_QUALITY_MEASUREMENT_SAMPLES) {
            val->val1 = sps30_measurement_samples_num;
    } else {
            return -ENOTSUP;
    }

    return 0;
}

/*
static int16_t sps30_get_serial(const struct device *dev, char* serial) {
    
    int16_t error;

    error = sensirion_i2c_write_cmd(dev, SPS_CMD_GET_SERIAL);

    if (error) {
        return error;
    }

    error = sensirion_i2c_read_words_as_bytes(
        dev, (uint8_t*)serial, SPS30_SERIAL_NUM_WORDS);

    // ensure a final '\0'. The firmware should always set this so this is just in case something goes wrong.
    
    serial[SPS30_MAX_SERIAL_LEN - 1] = '\0';

    return error;
}
*/
/*
static int sps30_read_firmware_version(const struct device *dev, uint8_t* major, uint8_t* minor) {
    
    uint16_t version;
    int ret;

    ret = sensirion_i2c_read_cmd(dev,
                                 SPS_CMD_GET_FIRMWARE_VERSION, &version, 1);
    *major = (version & 0xff00) >> 8;
    *minor = (version & 0x00ff);
    
    return ret;
}

static int sps30_init(const struct device *dev)
{
    int ret;
    struct sps30_data *drv_dev = to_data(dev);

    ret = sps30_read_firmware_version(dev, &drv_dev->fw_major, &drv_dev->fw_minor);
    if (ret) {
		LOG_ERR("error reading firmware version\n");
    } else {
        printk("FW: %u.%u\n", drv_dev->fw_major, drv_dev->fw_minor);
    }
	
    ret = sps30_get_serial(dev, drv_dev->serial_number);

    if (ret) {
		LOG_ERR("error reading serial number\n");
    } else {
        printk("Serial Number: %s\n", drv_dev->serial_number);
    }

    //set manual fan cleaning
    sps30_set_fan_auto_cleaning_interval(dev,0);

    return ret;
}
*/
static const struct sensor_driver_api sps30_driver_api = {
    .sample_fetch = sps30_sample_fetch,
    .channel_get = sps30_channel_get,
    .attr_set = sps30_attr_set,
    .attr_get = sps30_attr_get
};

static int sps30_chip_init(const struct device *dev)
{
    //sps30_init(dev);
    return 0;
}

/* Initializes a struct sps30_config for an instance on an I2C bus. */
#define SPS30_CONFIG_I2C(inst)			       \
{					       \
        .bus = DEVICE_DT_GET(DT_INST_BUS(inst)), \
        .bus_io = &sps30_bus_io_i2c,	       \
        .bus_config.i2c_addr = DT_INST_REG_ADDR(inst),		\
}

#define SPS30_DEFINE(inst)						\
	static struct sps30_data sps30_data_##inst;			\
	static const struct sps30_config sps30_config_##inst =	\
		                SPS30_CONFIG_I2C(inst);    \
	DEVICE_DT_INST_DEFINE(inst,					\
			 sps30_chip_init,				\
			 NULL,				\
			 &sps30_data_##inst,				\
			 &sps30_config_##inst,				\
			 POST_KERNEL,					\
			 CONFIG_SENSOR_INIT_PRIORITY,			\
			 &sps30_driver_api);

/* Create the struct device for every status "okay" node in the devicetree. */
DT_INST_FOREACH_STATUS_OKAY(SPS30_DEFINE)
