linux/drivers/iio/proximity/sx9360.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2021 Google LLC.
 *
 * Driver for Semtech's SX9360 capacitive proximity/button solution.
 * Based on SX9360 driver and copy of datasheet at:
 * https://edit.wpgdadawant.com/uploads/news_file/program/2019/30184/tech_files/program_30184_suggest_other_file.pdf
 */

#include <linux/acpi.h>
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/property.h>
#include <linux/regmap.h>

#include <linux/iio/iio.h>

#include "sx_common.h"

/* Nominal Oscillator Frequency. */
#define SX9360_FOSC_MHZ
#define SX9360_FOSC_HZ

/* Register definitions. */
#define SX9360_REG_IRQ_SRC
#define SX9360_REG_STAT
#define SX9360_REG_STAT_COMPSTAT_MASK
#define SX9360_REG_IRQ_MSK
#define SX9360_CONVDONE_IRQ
#define SX9360_FAR_IRQ
#define SX9360_CLOSE_IRQ
#define SX9360_REG_IRQ_CFG

#define SX9360_REG_GNRL_CTRL0
#define SX9360_REG_GNRL_CTRL0_PHEN_MASK
#define SX9360_REG_GNRL_CTRL1
#define SX9360_REG_GNRL_CTRL1_SCANPERIOD_MASK
#define SX9360_REG_GNRL_CTRL2
#define SX9360_REG_GNRL_CTRL2_PERIOD_102MS
#define SX9360_REG_GNRL_REG_2_PERIOD_MS(_r)
#define SX9360_REG_GNRL_FREQ_2_REG(_f)
#define SX9360_REG_GNRL_REG_2_FREQ(_r)

#define SX9360_REG_AFE_CTRL1
#define SX9360_REG_AFE_CTRL1_RESFILTIN_MASK
#define SX9360_REG_AFE_CTRL1_RESFILTIN_0OHMS
#define SX9360_REG_AFE_PARAM0_PHR
#define SX9360_REG_AFE_PARAM1_PHR
#define SX9360_REG_AFE_PARAM0_PHM
#define SX9360_REG_AFE_PARAM0_RSVD
#define SX9360_REG_AFE_PARAM0_RESOLUTION_MASK
#define SX9360_REG_AFE_PARAM0_RESOLUTION_128
#define SX9360_REG_AFE_PARAM1_PHM
#define SX9360_REG_AFE_PARAM1_AGAIN_PHM_6PF
#define SX9360_REG_AFE_PARAM1_FREQ_83_33HZ

#define SX9360_REG_PROX_CTRL0_PHR
#define SX9360_REG_PROX_CTRL0_PHM
#define SX9360_REG_PROX_CTRL0_GAIN_MASK
#define SX9360_REG_PROX_CTRL0_GAIN_1
#define SX9360_REG_PROX_CTRL0_RAWFILT_MASK
#define SX9360_REG_PROX_CTRL0_RAWFILT_1P50
#define SX9360_REG_PROX_CTRL1
#define SX9360_REG_PROX_CTRL1_AVGNEG_THRESH_MASK
#define SX9360_REG_PROX_CTRL1_AVGNEG_THRESH_16K
#define SX9360_REG_PROX_CTRL2
#define SX9360_REG_PROX_CTRL2_AVGDEB_MASK
#define SX9360_REG_PROX_CTRL2_AVGDEB_2SAMPLES
#define SX9360_REG_PROX_CTRL2_AVGPOS_THRESH_16K
#define SX9360_REG_PROX_CTRL3
#define SX9360_REG_PROX_CTRL3_AVGNEG_FILT_MASK
#define SX9360_REG_PROX_CTRL3_AVGNEG_FILT_2
#define SX9360_REG_PROX_CTRL3_AVGPOS_FILT_MASK
#define SX9360_REG_PROX_CTRL3_AVGPOS_FILT_256
#define SX9360_REG_PROX_CTRL4
#define SX9360_REG_PROX_CTRL4_HYST_MASK
#define SX9360_REG_PROX_CTRL4_CLOSE_DEBOUNCE_MASK
#define SX9360_REG_PROX_CTRL4_FAR_DEBOUNCE_MASK
#define SX9360_REG_PROX_CTRL5
#define SX9360_REG_PROX_CTRL5_PROXTHRESH_32

#define SX9360_REG_REF_CORR0
#define SX9360_REG_REF_CORR1

#define SX9360_REG_USEFUL_PHR_MSB
#define SX9360_REG_USEFUL_PHR_LSB

#define SX9360_REG_OFFSET_PMR_MSB
#define SX9360_REG_OFFSET_PMR_LSB

#define SX9360_REG_USEFUL_PHM_MSB
#define SX9360_REG_USEFUL_PHM_LSB

#define SX9360_REG_AVG_PHM_MSB
#define SX9360_REG_AVG_PHM_LSB

#define SX9360_REG_DIFF_PHM_MSB
#define SX9360_REG_DIFF_PHM_LSB

#define SX9360_REG_OFFSET_PHM_MSB
#define SX9360_REG_OFFSET_PHM_LSB

#define SX9360_REG_USE_FILTER_MSB
#define SX9360_REG_USE_FILTER_LSB

#define SX9360_REG_RESET
/* Write this to REG_RESET to do a soft reset. */
#define SX9360_SOFT_RESET

#define SX9360_REG_WHOAMI
#define SX9360_WHOAMI_VALUE

#define SX9360_REG_REVISION

/* 2 channels, Phase Reference and Measurement. */
#define SX9360_NUM_CHANNELS

static const struct iio_chan_spec sx9360_channels[] =;

/*
 * Each entry contains the integer part (val) and the fractional part, in micro
 * seconds. It conforms to the IIO output IIO_VAL_INT_PLUS_MICRO.
 *
 * The frequency control register holds the period, with a ~2ms increment.
 * Therefore the smallest frequency is 4MHz / (2047 * 8192),
 * The fastest is 4MHz / 8192.
 * The interval is not linear, but given there is 2047 possible value,
 * Returns the fake increment of (Max-Min)/2047
 */
static const struct {} sx9360_samp_freq_interval[] =;

static const struct regmap_range sx9360_writable_reg_ranges[] =;

static const struct regmap_access_table sx9360_writeable_regs =;

/*
 * All allocated registers are readable, so we just list unallocated
 * ones.
 */
static const struct regmap_range sx9360_non_readable_reg_ranges[] =;

static const struct regmap_access_table sx9360_readable_regs =;

static const struct regmap_range sx9360_volatile_reg_ranges[] =;

static const struct regmap_access_table sx9360_volatile_regs =;

static const struct regmap_config sx9360_regmap_config =;

static int sx9360_read_prox_data(struct sx_common_data *data,
				 const struct iio_chan_spec *chan,
				 __be16 *val)
{}

/*
 * If we have no interrupt support, we have to wait for a scan period
 * after enabling a channel to get a result.
 */
static int sx9360_wait_for_sample(struct sx_common_data *data)
{}

static int sx9360_read_gain(struct sx_common_data *data,
			    const struct iio_chan_spec *chan, int *val)
{}

static int sx9360_read_samp_freq(struct sx_common_data *data,
				 int *val, int *val2)
{}

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

static const char *sx9360_channel_labels[SX9360_NUM_CHANNELS] =;

static int sx9360_read_label(struct iio_dev *iio_dev, const struct iio_chan_spec *chan,
			     char *label)
{}

static const int sx9360_gain_vals[] =;

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

static int sx9360_set_samp_freq(struct sx_common_data *data,
				int val, int val2)
{}

static int sx9360_read_thresh(struct sx_common_data *data, int *val)
{}

static int sx9360_read_hysteresis(struct sx_common_data *data, int *val)
{}

static int sx9360_read_far_debounce(struct sx_common_data *data, int *val)
{}

static int sx9360_read_close_debounce(struct sx_common_data *data, int *val)
{}

static int sx9360_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 sx9360_write_thresh(struct sx_common_data *data, int _val)
{}

static int sx9360_write_hysteresis(struct sx_common_data *data, int _val)
{}

static int sx9360_write_far_debounce(struct sx_common_data *data, int _val)
{}

static int sx9360_write_close_debounce(struct sx_common_data *data, int _val)
{}

static int sx9360_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 sx9360_write_gain(struct sx_common_data *data,
			     const struct iio_chan_spec *chan, int val)
{}

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

static const struct sx_common_reg_default sx9360_default_regs[] =;

/* Activate all channels and perform an initial compensation. */
static int sx9360_init_compensation(struct iio_dev *indio_dev)
{}

static const struct sx_common_reg_default *
sx9360_get_default_reg(struct device *dev, int idx,
		       struct sx_common_reg_default *reg_def)
{}

static int sx9360_check_whoami(struct device *dev, struct iio_dev *indio_dev)
{}

static const struct sx_common_chip_info sx9360_chip_info =;

static int sx9360_probe(struct i2c_client *client)
{}

static int sx9360_suspend(struct device *dev)
{}

static int sx9360_resume(struct device *dev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(sx9360_pm_ops, sx9360_suspend, sx9360_resume);

static const struct acpi_device_id sx9360_acpi_match[] =;
MODULE_DEVICE_TABLE(acpi, sx9360_acpi_match);

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

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

static struct i2c_driver sx9360_driver =;
module_i2c_driver();

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