linux/drivers/iio/light/veml6030.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * VEML6030 Ambient Light Sensor
 *
 * Copyright (c) 2019, Rishi Gupta <[email protected]>
 *
 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf
 * Appnote-84367: https://www.vishay.com/docs/84367/designingveml6030.pdf
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>

/* Device registers */
#define VEML6030_REG_ALS_CONF
#define VEML6030_REG_ALS_WH
#define VEML6030_REG_ALS_WL
#define VEML6030_REG_ALS_PSM
#define VEML6030_REG_ALS_DATA
#define VEML6030_REG_WH_DATA
#define VEML6030_REG_ALS_INT

/* Bit masks for specific functionality */
#define VEML6030_ALS_IT
#define VEML6030_PSM
#define VEML6030_ALS_PERS
#define VEML6030_ALS_GAIN
#define VEML6030_PSM_EN
#define VEML6030_INT_TH_LOW
#define VEML6030_INT_TH_HIGH
#define VEML6030_ALS_INT_EN
#define VEML6030_ALS_SD

/*
 * The resolution depends on both gain and integration time. The
 * cur_resolution stores one of the resolution mentioned in the
 * table during startup and gets updated whenever integration time
 * or gain is changed.
 *
 * Table 'resolution and maximum detection range' in appnote 84367
 * is visualized as a 2D array. The cur_gain stores index of gain
 * in this table (0-3) while the cur_integration_time holds index
 * of integration time (0-5).
 */
struct veml6030_data {};

/* Integration time available in seconds */
static IIO_CONST_ATTR(in_illuminance_integration_time_available,
				"0.025 0.05 0.1 0.2 0.4 0.8");

/*
 * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is
 * ALS gain x (1/4), 1.0 = ALS gain x 1 and 2.0 is ALS gain x 2.
 */
static IIO_CONST_ATTR(in_illuminance_scale_available,
				"0.125 0.25 1.0 2.0");

static struct attribute *veml6030_attributes[] =;

static const struct attribute_group veml6030_attr_group =;

/*
 * Persistence = 1/2/4/8 x integration time
 * Minimum time for which light readings must stay above configured
 * threshold to assert the interrupt.
 */
static const char * const period_values[] =;

/*
 * Return list of valid period values in seconds corresponding to
 * the currently active integration time.
 */
static ssize_t in_illuminance_period_available_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{}

static IIO_DEVICE_ATTR_RO(in_illuminance_period_available, 0);

static struct attribute *veml6030_event_attributes[] =;

static const struct attribute_group veml6030_event_attr_group =;

static int veml6030_als_pwr_on(struct veml6030_data *data)
{}

static int veml6030_als_shut_down(struct veml6030_data *data)
{}

static void veml6030_als_shut_down_action(void *data)
{}

static const struct iio_event_spec veml6030_event_spec[] =;

/* Channel number */
enum veml6030_chan {};

static const struct iio_chan_spec veml6030_channels[] =;

static const struct regmap_config veml6030_regmap_config =;

static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev,
						int *val, int *val2)
{}

static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev,
						int val, int val2)
{}

static int veml6030_read_persistence(struct iio_dev *indio_dev,
						int *val, int *val2)
{}

static int veml6030_write_persistence(struct iio_dev *indio_dev,
						int val, int val2)
{}

static int veml6030_set_als_gain(struct iio_dev *indio_dev,
						int val, int val2)
{}

static int veml6030_get_als_gain(struct iio_dev *indio_dev,
						int *val, int *val2)
{}

static int veml6030_read_thresh(struct iio_dev *indio_dev,
						int *val, int *val2, int dir)
{}

static int veml6030_write_thresh(struct iio_dev *indio_dev,
						int val, int val2, int dir)
{}

/*
 * Provide both raw as well as light reading in lux.
 * light (in lux) = resolution * raw reading
 */
static int veml6030_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{}

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

static int veml6030_read_event_val(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 veml6030_write_event_val(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 veml6030_read_interrupt_config(struct iio_dev *indio_dev,
		const struct iio_chan_spec *chan, enum iio_event_type type,
		enum iio_event_direction dir)
{}

/*
 * Sensor should not be measuring light when interrupt is configured.
 * Therefore correct sequence to configure interrupt functionality is:
 * shut down -> enable/disable interrupt -> power on
 *
 * state = 1 enables interrupt, state = 0 disables interrupt
 */
static int veml6030_write_interrupt_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 veml6030_info =;

static const struct iio_info veml6030_info_no_irq =;

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

/*
 * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2,
 * persistence to 1 x integration time and the threshold
 * interrupt disabled by default. First shutdown the sensor,
 * update registers and then power on the sensor.
 */
static int veml6030_hw_init(struct iio_dev *indio_dev)
{}

static int veml6030_probe(struct i2c_client *client)
{}

static int veml6030_runtime_suspend(struct device *dev)
{}

static int veml6030_runtime_resume(struct device *dev)
{}

static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend,
				 veml6030_runtime_resume, NULL);

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

static const struct i2c_device_id veml6030_id[] =;
MODULE_DEVICE_TABLE(i2c, veml6030_id);

static struct i2c_driver veml6030_driver =;
module_i2c_driver();

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