// SPDX-License-Identifier: GPL-2.0-only
/*
* Analog Devices AD4851 DAS driver
*
* Copyright 2024 Analog Devices Inc.
*/
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/minmax.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/types.h>
#include <linux/unaligned.h>
#include <linux/units.h>
#include <linux/iio/backend.h>
#include <linux/iio/iio.h>
#define AD4851_REG_INTERFACE_CONFIG_A 0x00
#define AD4851_REG_INTERFACE_CONFIG_B 0x01
#define AD4851_REG_PRODUCT_ID_L 0x04
#define AD4851_REG_PRODUCT_ID_H 0x05
#define AD4851_REG_DEVICE_CTRL 0x25
#define AD4851_REG_PACKET 0x26
#define AD4851_REG_OVERSAMPLE 0x27
#define AD4851_REG_CH_CONFIG_BASE 0x2A
#define AD4851_REG_CHX_SOFTSPAN(ch) ((0x12 * (ch)) + AD4851_REG_CH_CONFIG_BASE)
#define AD4851_REG_CHX_OFFSET(ch) (AD4851_REG_CHX_SOFTSPAN(ch) + 0x01)
#define AD4851_REG_CHX_OFFSET_LSB(ch) AD4851_REG_CHX_OFFSET(ch)
#define AD4851_REG_CHX_OFFSET_MID(ch) (AD4851_REG_CHX_OFFSET_LSB(ch) + 0x01)
#define AD4851_REG_CHX_OFFSET_MSB(ch) (AD4851_REG_CHX_OFFSET_MID(ch) + 0x01)
#define AD4851_REG_CHX_GAIN(ch) (AD4851_REG_CHX_OFFSET(ch) + 0x03)
#define AD4851_REG_CHX_GAIN_LSB(ch) AD4851_REG_CHX_GAIN(ch)
#define AD4851_REG_CHX_GAIN_MSB(ch) (AD4851_REG_CHX_GAIN(ch) + 0x01)
#define AD4851_REG_CHX_PHASE(ch) (AD4851_REG_CHX_GAIN(ch) + 0x02)
#define AD4851_REG_CHX_PHASE_LSB(ch) AD4851_REG_CHX_PHASE(ch)
#define AD4851_REG_CHX_PHASE_MSB(ch) (AD4851_REG_CHX_PHASE_LSB(ch) + 0x01)
#define AD4851_REG_TESTPAT_0(c) (0x38 + (c) * 0x12)
#define AD4851_REG_TESTPAT_1(c) (0x39 + (c) * 0x12)
#define AD4851_REG_TESTPAT_2(c) (0x3A + (c) * 0x12)
#define AD4851_REG_TESTPAT_3(c) (0x3B + (c) * 0x12)
#define AD4851_SW_RESET (BIT(7) | BIT(0))
#define AD4851_SDO_ENABLE BIT(4)
#define AD4851_SINGLE_INSTRUCTION BIT(7)
#define AD4851_REFBUF BIT(2)
#define AD4851_REFSEL BIT(1)
#define AD4851_ECHO_CLOCK_MODE BIT(0)
#define AD4851_PACKET_FORMAT_0 0
#define AD4851_PACKET_FORMAT_1 1
#define AD4851_PACKET_FORMAT_MASK GENMASK(1, 0)
#define AD4851_OS_EN_MSK BIT(7)
#define AD4851_OS_RATIO_MSK GENMASK(3, 0)
#define AD4851_TEST_PAT BIT(2)
#define AD4858_PACKET_SIZE_20 0
#define AD4858_PACKET_SIZE_24 1
#define AD4858_PACKET_SIZE_32 2
#define AD4857_PACKET_SIZE_16 0
#define AD4857_PACKET_SIZE_24 1
#define AD4851_TESTPAT_0_DEFAULT 0x2A
#define AD4851_TESTPAT_1_DEFAULT 0x3C
#define AD4851_TESTPAT_2_DEFAULT 0xCE
#define AD4851_TESTPAT_3_DEFAULT(c) (0x0A + (0x10 * (c)))
#define AD4851_SOFTSPAN_0V_2V5 0
#define AD4851_SOFTSPAN_N2V5_2V5 1
#define AD4851_SOFTSPAN_0V_5V 2
#define AD4851_SOFTSPAN_N5V_5V 3
#define AD4851_SOFTSPAN_0V_6V25 4
#define AD4851_SOFTSPAN_N6V25_6V25 5
#define AD4851_SOFTSPAN_0V_10V 6
#define AD4851_SOFTSPAN_N10V_10V 7
#define AD4851_SOFTSPAN_0V_12V5 8
#define AD4851_SOFTSPAN_N12V5_12V5 9
#define AD4851_SOFTSPAN_0V_20V 10
#define AD4851_SOFTSPAN_N20V_20V 11
#define AD4851_SOFTSPAN_0V_25V 12
#define AD4851_SOFTSPAN_N25V_25V 13
#define AD4851_SOFTSPAN_0V_40V 14
#define AD4851_SOFTSPAN_N40V_40V 15
#define AD4851_MAX_LANES 8
#define AD4851_MAX_IODELAY 32
#define AD4851_T_CNVH_NS 40
#define AD4851_T_CNVH_NS_MARGIN 10
#define AD4841_MAX_SCALE_AVAIL 8
#define AD4851_MAX_CH_NR 8
#define AD4851_CH_START 0
struct ad4851_scale {
unsigned int scale_val;
u8 reg_val;
};
static const struct ad4851_scale ad4851_scale_table_unipolar[] = {
{ 2500, 0x0 },
{ 5000, 0x2 },
{ 6250, 0x4 },
{ 10000, 0x6 },
{ 12500, 0x8 },
{ 20000, 0xA },
{ 25000, 0xC },
{ 40000, 0xE },
};
static const struct ad4851_scale ad4851_scale_table_bipolar[] = {
{ 5000, 0x1 },
{ 10000, 0x3 },
{ 12500, 0x5 },
{ 20000,