#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <linux/units.h>
#include <linux/iio/iio.h>
#include <linux/iio/iio-gts-helper.h>
#include <linux/iio/events.h>
#include <linux/iio/sysfs.h>
#include <linux/unaligned.h>
#define APDS9306_MAIN_CTRL_REG …
#define APDS9306_ALS_MEAS_RATE_REG …
#define APDS9306_ALS_GAIN_REG …
#define APDS9306_PART_ID_REG …
#define APDS9306_MAIN_STATUS_REG …
#define APDS9306_CLEAR_DATA_0_REG …
#define APDS9306_CLEAR_DATA_1_REG …
#define APDS9306_CLEAR_DATA_2_REG …
#define APDS9306_ALS_DATA_0_REG …
#define APDS9306_ALS_DATA_1_REG …
#define APDS9306_ALS_DATA_2_REG …
#define APDS9306_INT_CFG_REG …
#define APDS9306_INT_PERSISTENCE_REG …
#define APDS9306_ALS_THRES_UP_0_REG …
#define APDS9306_ALS_THRES_UP_1_REG …
#define APDS9306_ALS_THRES_UP_2_REG …
#define APDS9306_ALS_THRES_LOW_0_REG …
#define APDS9306_ALS_THRES_LOW_1_REG …
#define APDS9306_ALS_THRES_LOW_2_REG …
#define APDS9306_ALS_THRES_VAR_REG …
#define APDS9306_ALS_INT_STAT_MASK …
#define APDS9306_ALS_DATA_STAT_MASK …
#define APDS9306_ALS_THRES_VAL_MAX …
#define APDS9306_ALS_THRES_VAR_NUM_VALS …
#define APDS9306_ALS_PERSIST_NUM_VALS …
#define APDS9306_ALS_READ_DATA_DELAY_US …
#define APDS9306_NUM_REPEAT_RATES …
#define APDS9306_INT_SRC_CLEAR …
#define APDS9306_INT_SRC_ALS …
#define APDS9306_SAMP_FREQ_10HZ …
struct part_id_gts_multiplier { … };
static const struct part_id_gts_multiplier apds9306_gts_mul[] = …;
static const int apds9306_repeat_rate_freq[APDS9306_NUM_REPEAT_RATES][2] = …;
static const int apds9306_repeat_rate_period[APDS9306_NUM_REPEAT_RATES] = …;
struct apds9306_regfields { … };
struct apds9306_data { … };
#define APDS9306_GSEL_1X …
#define APDS9306_GSEL_3X …
#define APDS9306_GSEL_6X …
#define APDS9306_GSEL_9X …
#define APDS9306_GSEL_18X …
static const struct iio_gain_sel_pair apds9306_gains[] = …;
#define APDS9306_MEAS_MODE_400MS …
#define APDS9306_MEAS_MODE_200MS …
#define APDS9306_MEAS_MODE_100MS …
#define APDS9306_MEAS_MODE_50MS …
#define APDS9306_MEAS_MODE_25MS …
#define APDS9306_MEAS_MODE_3125US …
static const struct iio_itime_sel_mul apds9306_itimes[] = …;
static const struct iio_event_spec apds9306_event_spec[] = …;
static const struct iio_chan_spec apds9306_channels_with_events[] = …;
static const struct iio_chan_spec apds9306_channels_without_events[] = …;
static IIO_CONST_ATTR(thresh_either_period_available, "[0 1 15]");
static IIO_CONST_ATTR(thresh_adaptive_either_values_available, "[0 1 7]");
static struct attribute *apds9306_event_attributes[] = …;
static const struct attribute_group apds9306_event_attr_group = …;
static const struct regmap_range apds9306_readable_ranges[] = …;
static const struct regmap_range apds9306_writable_ranges[] = …;
static const struct regmap_range apds9306_volatile_ranges[] = …;
static const struct regmap_range apds9306_precious_ranges[] = …;
static const struct regmap_access_table apds9306_readable_table = …;
static const struct regmap_access_table apds9306_writable_table = …;
static const struct regmap_access_table apds9306_volatile_table = …;
static const struct regmap_access_table apds9306_precious_table = …;
static const struct regmap_config apds9306_regmap = …;
static const struct reg_field apds9306_rf_sw_reset = …;
static const struct reg_field apds9306_rf_en = …;
static const struct reg_field apds9306_rf_intg_time = …;
static const struct reg_field apds9306_rf_repeat_rate = …;
static const struct reg_field apds9306_rf_gain = …;
static const struct reg_field apds9306_rf_int_src = …;
static const struct reg_field apds9306_rf_int_thresh_var_en = …;
static const struct reg_field apds9306_rf_int_en = …;
static const struct reg_field apds9306_rf_int_persist_val = …;
static const struct reg_field apds9306_rf_int_thresh_var_val = …;
static int apds9306_regfield_init(struct apds9306_data *data)
{ … }
static int apds9306_power_state(struct apds9306_data *data, bool state)
{ … }
static int apds9306_read_data(struct apds9306_data *data, int *val, int reg)
{ … }
static int apds9306_intg_time_get(struct apds9306_data *data, int *val2)
{ … }
static int apds9306_intg_time_set(struct apds9306_data *data, int val2)
{ … }
static int apds9306_sampling_freq_get(struct apds9306_data *data, int *val,
int *val2)
{ … }
static int apds9306_sampling_freq_set(struct apds9306_data *data, int val,
int val2)
{ … }
static int apds9306_scale_get(struct apds9306_data *data, int *val, int *val2)
{ … }
static int apds9306_scale_set(struct apds9306_data *data, int val, int val2)
{ … }
static int apds9306_event_period_get(struct apds9306_data *data, int *val)
{ … }
static int apds9306_event_period_set(struct apds9306_data *data, int val)
{ … }
static int apds9306_event_thresh_get(struct apds9306_data *data, int dir,
int *val)
{ … }
static int apds9306_event_thresh_set(struct apds9306_data *data, int dir,
int val)
{ … }
static int apds9306_event_thresh_adaptive_get(struct apds9306_data *data, int *val)
{ … }
static int apds9306_event_thresh_adaptive_set(struct apds9306_data *data, int val)
{ … }
static int apds9306_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long mask)
{
struct apds9306_data *data = iio_priv(indio_dev);
int ret, reg;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->channel2 == IIO_MOD_LIGHT_CLEAR)
reg = APDS9306_CLEAR_DATA_0_REG;
else
reg = APDS9306_ALS_DATA_0_REG;
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = apds9306_read_data(data, val, reg);
iio_device_release_direct_mode(indio_dev);
if (ret)
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_INT_TIME:
ret = apds9306_intg_time_get(data, val2);
if (ret)
return ret;
*val = 0;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SAMP_FREQ:
ret = apds9306_sampling_freq_get(data, val, val2);
if (ret)
return ret;
return IIO_VAL_INT_PLUS_MICRO;
case IIO_CHAN_INFO_SCALE:
ret = apds9306_scale_get(data, val, val2);
if (ret)
return ret;
return IIO_VAL_INT_PLUS_NANO;
default:
return -EINVAL;
}
};
static int apds9306_read_avail(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
const int **vals, int *type, int *length,
long mask)
{ … }
static int apds9306_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{ … }
static int apds9306_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int val,
int val2, long mask)
{ … }
static irqreturn_t apds9306_irq_handler(int irq, void *priv)
{ … }
static int apds9306_read_event(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 apds9306_write_event(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 apds9306_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 apds9306_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 apds9306_info_no_events = …;
static const struct iio_info apds9306_info = …;
static int apds9306_init_iio_gts(struct apds9306_data *data)
{ … }
static void apds9306_powerdown(void *ptr)
{ … }
static int apds9306_device_init(struct apds9306_data *data)
{ … }
static int apds9306_pm_init(struct apds9306_data *data)
{ … }
static int apds9306_probe(struct i2c_client *client)
{ … }
static int apds9306_runtime_suspend(struct device *dev)
{ … }
static int apds9306_runtime_resume(struct device *dev)
{ … }
static DEFINE_RUNTIME_DEV_PM_OPS(apds9306_pm_ops,
apds9306_runtime_suspend,
apds9306_runtime_resume,
NULL);
static const struct of_device_id apds9306_of_match[] = …;
MODULE_DEVICE_TABLE(of, apds9306_of_match);
static struct i2c_driver apds9306_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;
MODULE_IMPORT_NS(…);