linux/drivers/iio/adc/ti-tsc2046.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Texas Instruments TSC2046 SPI ADC driver
 *
 * Copyright (c) 2021 Oleksij Rempel <[email protected]>, Pengutronix
 */

#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/units.h>

#include <asm/unaligned.h>

#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger.h>

/*
 * The PENIRQ of TSC2046 controller is implemented as level shifter attached to
 * the X+ line. If voltage of the X+ line reaches a specific level the IRQ will
 * be activated or deactivated.
 * To make this kind of IRQ reusable as trigger following additions were
 * implemented:
 * - rate limiting:
 *   For typical touchscreen use case, we need to trigger about each 10ms.
 * - hrtimer:
 *   Continue triggering at least once after the IRQ was deactivated. Then
 *   deactivate this trigger to stop sampling in order to reduce power
 *   consumption.
 */

#define TI_TSC2046_NAME

/* This driver doesn't aim at the peak continuous sample rate */
#define TI_TSC2046_MAX_SAMPLE_RATE
#define TI_TSC2046_SAMPLE_BITS
#define TI_TSC2046_MAX_CLK_FREQ

#define TI_TSC2046_SAMPLE_INTERVAL_US

#define TI_TSC2046_START
#define TI_TSC2046_ADDR
#define TI_TSC2046_ADDR_TEMP1
#define TI_TSC2046_ADDR_AUX
#define TI_TSC2046_ADDR_X
#define TI_TSC2046_ADDR_Z2
#define TI_TSC2046_ADDR_Z1
#define TI_TSC2046_ADDR_VBAT
#define TI_TSC2046_ADDR_Y
#define TI_TSC2046_ADDR_TEMP0

/*
 * The mode bit sets the resolution of the ADC. With this bit low, the next
 * conversion has 12-bit resolution, whereas with this bit high, the next
 * conversion has 8-bit resolution. This driver is optimized for 12-bit mode.
 * So, for this driver, this bit should stay zero.
 */
#define TI_TSC2046_8BIT_MODE

/*
 * SER/DFR - The SER/DFR bit controls the reference mode, either single-ended
 * (high) or differential (low).
 */
#define TI_TSC2046_SER

/*
 * If VREF_ON and ADC_ON are both zero, then the chip operates in
 * auto-wake/suspend mode. In most case this bits should stay zero.
 */
#define TI_TSC2046_PD1_VREF_ON
#define TI_TSC2046_PD0_ADC_ON

/*
 * All supported devices can do 8 or 12bit resolution. This driver
 * supports only 12bit mode, here we have a 16bit data transfer, where
 * the MSB and the 3 LSB are 0.
 */
#define TI_TSC2046_DATA_12BIT

#define TI_TSC2046_MAX_CHAN
#define TI_TSC2046_MIN_POLL_CNT
#define TI_TSC2046_EXT_POLL_CNT
#define TI_TSC2046_POLL_CNT
#define TI_TSC2046_INT_VREF

/* Represents a HW sample */
struct tsc2046_adc_atom {} __packed;

/* Layout of atomic buffers within big buffer */
struct tsc2046_adc_group_layout {};

struct tsc2046_adc_dcfg {};

struct tsc2046_adc_ch_cfg {};

enum tsc2046_state {};

struct tsc2046_adc_priv {};

#define TI_TSC2046_V_CHAN(index, bits, name)

#define DECLARE_TI_TSC2046_8_CHANNELS(name, bits)

static DECLARE_TI_TSC2046_8_CHANNELS(tsc2046_adc, 12);

static const struct tsc2046_adc_dcfg tsc2046_adc_dcfg_tsc2046e =;

/*
 * Convert time to a number of samples which can be transferred within this
 * time.
 */
static unsigned int tsc2046_adc_time_to_count(struct tsc2046_adc_priv *priv,
					      unsigned long time)
{}

static u8 tsc2046_adc_get_cmd(struct tsc2046_adc_priv *priv, int ch_idx,
			      bool keep_power)
{}

static u16 tsc2046_adc_get_value(struct tsc2046_adc_atom *buf)
{}

static int tsc2046_adc_read_one(struct tsc2046_adc_priv *priv, int ch_idx,
				u32 *effective_speed_hz)
{}

static size_t tsc2046_adc_group_set_layout(struct tsc2046_adc_priv *priv,
					   unsigned int group,
					   unsigned int ch_idx)
{}

static void tsc2046_adc_group_set_cmd(struct tsc2046_adc_priv *priv,
				      unsigned int group, int ch_idx)
{}

static u16 tsc2046_adc_get_val(struct tsc2046_adc_priv *priv, int group)
{}

static int tsc2046_adc_scan(struct iio_dev *indio_dev)
{}

static irqreturn_t tsc2046_adc_trigger_handler(int irq, void *p)
{}

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

static int tsc2046_adc_update_scan_mode(struct iio_dev *indio_dev,
					const unsigned long *active_scan_mask)
{}

static const struct iio_info tsc2046_adc_info =;

static enum hrtimer_restart tsc2046_adc_timer(struct hrtimer *hrtimer)
{}

static irqreturn_t tsc2046_adc_irq(int irq, void *dev_id)
{}

static void tsc2046_adc_reenable_trigger(struct iio_trigger *trig)
{}

static int tsc2046_adc_set_trigger_state(struct iio_trigger *trig, bool enable)
{}

static const struct iio_trigger_ops tsc2046_adc_trigger_ops =;

static int tsc2046_adc_setup_spi_msg(struct tsc2046_adc_priv *priv)
{}

static void tsc2046_adc_parse_fwnode(struct tsc2046_adc_priv *priv)
{}

static void tsc2046_adc_regulator_disable(void *data)
{}

static int tsc2046_adc_configure_regulator(struct tsc2046_adc_priv *priv)
{}

static int tsc2046_adc_probe(struct spi_device *spi)
{}

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

static const struct spi_device_id tsc2046_adc_spi_ids[] =;
MODULE_DEVICE_TABLE(spi, tsc2046_adc_spi_ids);

static struct spi_driver tsc2046_adc_driver =;
module_spi_driver();

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