blob: 07824f9214d59fdfa45ddc0fdcea6fb031fb7412 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regulator/consumer.h>
#include <linux/thermal.h>
enum meson_sar_adc_vref_sel {
CALIB_VOL_AS_VREF = 0,
VDDA_AS_VREF = 1,
};
enum meson_sar_adc_chan7_mux_sel {
CHAN7_MUX_VSS = 0x0,
CHAN7_MUX_VDD_DIV4 = 0x1,
CHAN7_MUX_VDD_DIV2 = 0x2,
CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
CHAN7_MUX_VDD = 0x4,
CHAN7_MUX_CH7_INPUT = 0x7,
};
enum meson_sar_adc_sampling_mode {
SINGLE_MODE,
PERIOD_MODE,
MAX_MODE,
};
struct meson_sar_adc_diff_ops {
int (*extra_init)(struct iio_dev *indio_dev);
void (*set_ch7_mux)(struct iio_dev *indio_dev,
enum meson_sar_adc_chan7_mux_sel sel);
int (*read_fifo)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, bool chk_channel);
void (*enable_chnl)(struct iio_dev *indio_dev, bool en);
int (*read_chnl)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan);
void (*set_bandgap)(struct iio_dev *indio_dev, bool on_off);
void (*select_temp)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan);
void (*init_ch)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan);
void (*enable_decim_filter)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, bool en);
int (*tuning_clock)(struct iio_dev *indio_dev,
enum meson_sar_adc_sampling_mode mode);
int (*temp_triming)(struct iio_dev *indio_dev);
void (*store_triming_val)(struct iio_dev *indio_dev);
};
/* struct meson_sar_adc_param - describe the differences of different platform
*
* @has_bl30_integration: g12a and later SoCs don not use saradc to sample
* internal temp sensor in bl30
*
* @resolution: gxl and later: 12bit; others(gxtvbb etc): 10bit
*
* @vref_is_optional: txlx and later SoCs support VDDA or Calibration Voltage
* as vref, but others support only Calibration Voltage
*
* @disable_ring_counter: gxl and later SoCs write 1 to disable continuous ring
* counter, but others write 0
*
* @has_chnl_regs: enable period sampling mode when the SoCs contain chnl regs
*
* @vrefp_select: g12a and later SoCs must write 0, others SoC write 1
*
* @cmv_select: g12a and later SoCs must write 0, others SoC write 1
*
* @adc_eoc: g12a and later SoCs must write 1
*
* @calib_enable: enable sw calibration, TXL and before SoCs must write true,
* other SoCs are optional.
*/
struct meson_sar_adc_param {
u8 has_bl30_integration;
unsigned long clock_rate;
u32 bandgap_reg;
unsigned int resolution;
const struct regmap_config *regmap_config;
u8 temperature_trimming_bits;
unsigned int temperature_multiplier;
unsigned int temperature_divider;
const struct meson_sar_adc_diff_ops *dops;
const struct iio_chan_spec *channels;
u8 num_channels;
u8 vref_is_optional;
u8 disable_ring_counter;
u8 has_chnl_regs;
u8 vrefp_select;
u8 cmv_select;
u8 adc_eoc;
u8 calib_enable;
};
struct meson_sar_adc_priv {
struct regmap *regmap;
struct regulator *vref;
const struct meson_sar_adc_param *param;
struct clk *clkin;
struct clk *core_clk;
struct clk *adc_sel_clk;
struct clk *adc_clk;
struct clk_gate clk_gate;
struct clk *adc_div_clk;
struct clk_divider clk_div;
int calibbias;
int calibscale;
u8 temperature_sensor_calibrated;
u8 temperature_sensor_coefficient;
u16 temperature_sensor_adc_val;
int delay_per_tick;
int ticks_per_period;
int active_channel_cnt;
u8 *datum_buf;
u8 chan7_mux_sel;
u32 continuous_sample_count;
struct completion done;
u32 *continuous_sample_buffer;
u8 trimming_val;
struct thermal_zone_device *thermal_zone_dev;
struct delayed_work trim_poll_work;
};
extern const struct meson_sar_adc_param meson_sar_adc_meson8_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_meson8b_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_gxbb_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_gxl_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_txlx_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_g12a_param __initconst;
extern const struct meson_sar_adc_param meson_sar_adc_c2_param __initconst;