linux/drivers/iio/light/tsl2591.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2021 Joe Sandom <[email protected]>
 *
 * Datasheet: https://ams.com/tsl25911#tab/documents
 *
 * Device driver for the TAOS TSL2591. This is a very-high sensitivity
 * light-to-digital converter that transforms light intensity into a digital
 * signal.
 */

#include <linux/bitfield.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/sysfs.h>

#include <linux/unaligned.h>

#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

/* ADC integration time, field value to time in ms */
#define TSL2591_FVAL_TO_MSEC(x)
/* ADC integration time, field value to time in seconds */
#define TSL2591_FVAL_TO_SEC(x)
/* ADC integration time, time in seconds to field value */
#define TSL2591_SEC_TO_FVAL(x)

/* TSL2591 register set */
#define TSL2591_ENABLE
#define TSL2591_CONTROL
#define TSL2591_AILTL
#define TSL2591_AILTH
#define TSL2591_AIHTL
#define TSL2591_AIHTH
#define TSL2591_NP_AILTL
#define TSL2591_NP_AILTH
#define TSL2591_NP_AIHTL
#define TSL2591_NP_AIHTH
#define TSL2591_PERSIST
#define TSL2591_PACKAGE_ID
#define TSL2591_DEVICE_ID
#define TSL2591_STATUS
#define TSL2591_C0_DATAL
#define TSL2591_C0_DATAH
#define TSL2591_C1_DATAL
#define TSL2591_C1_DATAH

/* TSL2591 command register definitions */
#define TSL2591_CMD_NOP
#define TSL2591_CMD_SF_INTSET
#define TSL2591_CMD_SF_CALS_I
#define TSL2591_CMD_SF_CALS_NPI
#define TSL2591_CMD_SF_CNP_ALSI

/* TSL2591 enable register definitions */
#define TSL2591_PWR_ON
#define TSL2591_PWR_OFF
#define TSL2591_ENABLE_ALS
#define TSL2591_ENABLE_ALS_INT
#define TSL2591_ENABLE_SLEEP_INT
#define TSL2591_ENABLE_NP_INT

/* TSL2591 control register definitions */
#define TSL2591_CTRL_ALS_INTEGRATION_100MS
#define TSL2591_CTRL_ALS_INTEGRATION_200MS
#define TSL2591_CTRL_ALS_INTEGRATION_300MS
#define TSL2591_CTRL_ALS_INTEGRATION_400MS
#define TSL2591_CTRL_ALS_INTEGRATION_500MS
#define TSL2591_CTRL_ALS_INTEGRATION_600MS
#define TSL2591_CTRL_ALS_LOW_GAIN
#define TSL2591_CTRL_ALS_MED_GAIN
#define TSL2591_CTRL_ALS_HIGH_GAIN
#define TSL2591_CTRL_ALS_MAX_GAIN
#define TSL2591_CTRL_SYS_RESET

/* TSL2591 persist register definitions */
#define TSL2591_PRST_ALS_INT_CYCLE_0
#define TSL2591_PRST_ALS_INT_CYCLE_ANY
#define TSL2591_PRST_ALS_INT_CYCLE_2
#define TSL2591_PRST_ALS_INT_CYCLE_3
#define TSL2591_PRST_ALS_INT_CYCLE_5
#define TSL2591_PRST_ALS_INT_CYCLE_10
#define TSL2591_PRST_ALS_INT_CYCLE_15
#define TSL2591_PRST_ALS_INT_CYCLE_20
#define TSL2591_PRST_ALS_INT_CYCLE_25
#define TSL2591_PRST_ALS_INT_CYCLE_30
#define TSL2591_PRST_ALS_INT_CYCLE_35
#define TSL2591_PRST_ALS_INT_CYCLE_40
#define TSL2591_PRST_ALS_INT_CYCLE_45
#define TSL2591_PRST_ALS_INT_CYCLE_50
#define TSL2591_PRST_ALS_INT_CYCLE_55
#define TSL2591_PRST_ALS_INT_CYCLE_60
#define TSL2591_PRST_ALS_INT_CYCLE_MAX

/* TSL2591 PID register mask */
#define TSL2591_PACKAGE_ID_MASK

/* TSL2591 ID register mask */
#define TSL2591_DEVICE_ID_MASK

/* TSL2591 status register masks */
#define TSL2591_STS_ALS_VALID_MASK
#define TSL2591_STS_ALS_INT_MASK
#define TSL2591_STS_NPERS_INT_MASK
#define TSL2591_STS_VAL_HIGH_MASK

/* TSL2591 constant values */
#define TSL2591_PACKAGE_ID_VAL
#define TSL2591_DEVICE_ID_VAL

/* Power off suspend delay time MS */
#define TSL2591_POWER_OFF_DELAY_MS

/* TSL2591 default values */
#define TSL2591_DEFAULT_ALS_INT_TIME
#define TSL2591_DEFAULT_ALS_GAIN
#define TSL2591_DEFAULT_ALS_PERSIST
#define TSL2591_DEFAULT_ALS_LOWER_THRESH
#define TSL2591_DEFAULT_ALS_UPPER_THRESH

/* TSL2591 number of data registers */
#define TSL2591_NUM_DATA_REGISTERS

/* TSL2591 number of valid status reads on ADC complete */
#define TSL2591_ALS_STS_VALID_COUNT

/* TSL2591 delay period between polls when checking for ALS valid flag */
#define TSL2591_DELAY_PERIOD_US

/* TSL2591 maximum values */
#define TSL2591_MAX_ALS_INT_TIME_MS
#define TSL2591_ALS_MAX_VALUE

/*
 * LUX calculations;
 * AGAIN values from Adafruit's TSL2591 Arduino library
 * https://github.com/adafruit/Adafruit_TSL2591_Library
 */
#define TSL2591_CTRL_ALS_LOW_GAIN_MULTIPLIER
#define TSL2591_CTRL_ALS_MED_GAIN_MULTIPLIER
#define TSL2591_CTRL_ALS_HIGH_GAIN_MULTIPLIER
#define TSL2591_CTRL_ALS_MAX_GAIN_MULTIPLIER
#define TSL2591_LUX_COEFFICIENT

struct tsl2591_als_settings {};

struct tsl2591_chip {};

/*
 * Period table is ALS persist cycle x integration time setting
 * Integration times: 100ms, 200ms, 300ms, 400ms, 500ms, 600ms
 * ALS cycles: 1, 2, 3, 5, 10, 20, 25, 30, 35, 40, 45, 50, 55, 60
 */
static const char * const tsl2591_als_period_list[] =;

static const int tsl2591_int_time_available[] =;

static const int tsl2591_calibscale_available[] =;

static int tsl2591_set_als_lower_threshold(struct tsl2591_chip *chip,
					   u16 als_lower_threshold);
static int tsl2591_set_als_upper_threshold(struct tsl2591_chip *chip,
					   u16 als_upper_threshold);

static int tsl2591_gain_to_multiplier(const u8 als_gain)
{}

static int tsl2591_multiplier_to_gain(const u32 multiplier)
{}

static int tsl2591_persist_cycle_to_lit(const u8 als_persist)
{}

static int tsl2591_persist_lit_to_cycle(const u8 als_persist)
{}

static int tsl2591_compatible_int_time(struct tsl2591_chip *chip,
				       const u32 als_integration_time)
{}

static int tsl2591_als_time_to_fval(const u32 als_integration_time)
{}

static int tsl2591_compatible_gain(struct tsl2591_chip *chip, const u8 als_gain)
{}

static int tsl2591_compatible_als_persist_cycle(struct tsl2591_chip *chip,
						const u32 als_persist)
{}

static int tsl2591_check_als_valid(struct i2c_client *client)
{}

static int tsl2591_wait_adc_complete(struct tsl2591_chip *chip)
{}

/*
 * tsl2591_read_channel_data - Reads raw channel data and calculates lux
 *
 * Formula for lux calculation;
 * Derived from Adafruit's TSL2591 library
 * Link: https://github.com/adafruit/Adafruit_TSL2591_Library
 * Counts Per Lux (CPL) = (ATIME_ms * AGAIN) / LUX DF
 * lux = ((C0DATA - C1DATA) * (1 - (C1DATA / C0DATA))) / CPL
 *
 * Scale values to get more representative value of lux i.e.
 * lux = ((C0DATA - C1DATA) * (1000 - ((C1DATA * 1000) / C0DATA))) / CPL
 *
 * Channel 0 = IR + Visible
 * Channel 1 = IR only
 */
static int tsl2591_read_channel_data(struct iio_dev *indio_dev,
				     struct iio_chan_spec const *chan,
				     int *val, int *val2)
{}

static int tsl2591_set_als_gain_int_time(struct tsl2591_chip *chip)
{}

static int tsl2591_set_als_lower_threshold(struct tsl2591_chip *chip,
					   u16 als_lower_threshold)
{}

static int tsl2591_set_als_upper_threshold(struct tsl2591_chip *chip,
					   u16 als_upper_threshold)
{}

static int tsl2591_set_als_persist_cycle(struct tsl2591_chip *chip,
					 u8 als_persist)
{}

static int tsl2591_set_power_state(struct tsl2591_chip *chip, u8 state)
{}

static ssize_t tsl2591_in_illuminance_period_available_show(struct device *dev,
							    struct device_attribute *attr,
							    char *buf)
{}

static IIO_DEVICE_ATTR_RO(tsl2591_in_illuminance_period_available, 0);

static struct attribute *tsl2591_event_attrs_ctrl[] =;

static const struct attribute_group tsl2591_event_attribute_group =;

static const struct iio_event_spec tsl2591_events[] =;

static const struct iio_chan_spec tsl2591_channels[] =;

static int tsl2591_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{}

static int tsl2591_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     int val, int val2, long mask)
{}

static int tsl2591_read_available(struct iio_dev *indio_dev,
				  struct iio_chan_spec const *chan,
				  const int **vals, int *type, int *length,
				  long mask)
{}

static int tsl2591_read_event_value(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    enum iio_event_type type,
				    enum iio_event_direction dir,
				    enum iio_event_info info, int *val,
				    int *val2)
{}

static int tsl2591_write_event_value(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     enum iio_event_type type,
				     enum iio_event_direction dir,
				     enum iio_event_info info, int val,
				     int val2)
{}

static int tsl2591_read_event_config(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     enum iio_event_type type,
				     enum iio_event_direction dir)
{}

static int tsl2591_write_event_config(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      enum iio_event_type type,
				      enum iio_event_direction dir,
				      int state)
{}

static const struct iio_info tsl2591_info =;

static const struct iio_info tsl2591_info_no_irq =;

static int tsl2591_suspend(struct device *dev)
{}

static int tsl2591_resume(struct device *dev)
{}

static DEFINE_RUNTIME_DEV_PM_OPS(tsl2591_pm_ops, tsl2591_suspend,
				 tsl2591_resume, NULL);

static irqreturn_t tsl2591_event_handler(int irq, void *private)
{}

static int tsl2591_load_defaults(struct tsl2591_chip *chip)
{}

static void tsl2591_chip_off(void *data)
{}

static int tsl2591_probe(struct i2c_client *client)
{}

static const struct of_device_id tsl2591_of_match[] =;
MODULE_DEVICE_TABLE(of, tsl2591_of_match);

static struct i2c_driver tsl2591_driver =;
module_i2c_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();