iio: adc: meson-saradc: enable the temperature sensor two more SoCs
authorMartin Blumenstingl <martin.blumenstingl@googlemail.com>
Thu, 27 Dec 2018 21:50:20 +0000 (22:50 +0100)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 5 Jan 2019 16:42:05 +0000 (16:42 +0000)
Meson8b and Meson8m2 use the same logic to convert the ADC register
value to celsius, which is different from Meson8:
- Meson8 has different multiplier and divider values
- Meson8 uses a 4-bit TSC (temperature sensor coefficient) which fits
  into the 4-bit field in the MESON_SAR_ADC_DELTA_10 register:
  MESON_SAR_ADC_DELTA_10_TS_C_MASK. Meson8b and Meson8m2 have a 5-bit
  TSC which requires writing the upper-most bit into the
  MESON_HHI_DPLL_TOP_0[9] register from the HHI register area.

This adds support for the temperature sensor on the Meson8b and Meson8m2
SoCs by implementing the logic to write the upper-most TSC bit into the
HHI register area. The SoC-specific values (temperature_trimming_bits,
temperature_multiplier, temperature_divider) are added - these simply
integrate into the existing infrastructure (which was implemented for
Meson8) and thus require no further changes to the existing temperature
calculation logic.

Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/adc/meson_saradc.c

index 729becb..f8600fb 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/mfd/syscon.h>
 
 #define MESON_SAR_ADC_REG0                                     0x00
        #define MESON_SAR_ADC_REG0_PANEL_DETECT                 BIT(31)
 #define MESON_SAR_ADC_EFUSE_BYTE3_UPPER_ADC_VAL                        GENMASK(6, 0)
 #define MESON_SAR_ADC_EFUSE_BYTE3_IS_CALIBRATED                        BIT(7)
 
+#define MESON_HHI_DPLL_TOP_0                                   0x318
+#define MESON_HHI_DPLL_TOP_0_TSC_BIT4                          BIT(9)
+
 /* for use with IIO_VAL_INT_PLUS_MICRO */
 #define MILLION                                                        1000000
 
@@ -280,6 +284,7 @@ struct meson_sar_adc_priv {
        struct completion                       done;
        int                                     calibbias;
        int                                     calibscale;
+       struct regmap                           *tsc_regmap;
        bool                                    temperature_sensor_calibrated;
        u8                                      temperature_sensor_coefficient;
        u16                                     temperature_sensor_adc_val;
@@ -727,6 +732,15 @@ static int meson_sar_adc_temp_sensor_init(struct iio_dev *indio_dev)
                return ret;
        }
 
+       priv->tsc_regmap =
+               syscon_regmap_lookup_by_phandle(indio_dev->dev.parent->of_node,
+                                               "amlogic,hhi-sysctrl");
+       if (IS_ERR(priv->tsc_regmap)) {
+               dev_err(indio_dev->dev.parent,
+                       "failed to get amlogic,hhi-sysctrl regmap\n");
+               return PTR_ERR(priv->tsc_regmap);
+       }
+
        read_len = MESON_SAR_ADC_EFUSE_BYTES;
        buf = nvmem_cell_read(temperature_calib, &read_len);
        if (IS_ERR(buf)) {
@@ -861,6 +875,22 @@ static int meson_sar_adc_init(struct iio_dev *indio_dev)
                                    priv->temperature_sensor_coefficient);
                regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
                                   MESON_SAR_ADC_DELTA_10_TS_C_MASK, regval);
+
+               if (priv->param->temperature_trimming_bits == 5) {
+                       if (priv->temperature_sensor_coefficient & BIT(4))
+                               regval = MESON_HHI_DPLL_TOP_0_TSC_BIT4;
+                       else
+                               regval = 0;
+
+                       /*
+                        * bit [4] (the 5th bit when starting to count at 1)
+                        * of the TSC is located in the HHI register area.
+                        */
+                       regmap_update_bits(priv->tsc_regmap,
+                                          MESON_HHI_DPLL_TOP_0,
+                                          MESON_HHI_DPLL_TOP_0_TSC_BIT4,
+                                          regval);
+               }
        } else {
                regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
                                   MESON_SAR_ADC_DELTA_10_TS_REVE1, 0);
@@ -1064,6 +1094,9 @@ static const struct meson_sar_adc_param meson_sar_adc_meson8b_param = {
        .bandgap_reg = MESON_SAR_ADC_DELTA_10,
        .regmap_config = &meson_sar_adc_regmap_config_meson8,
        .resolution = 10,
+       .temperature_trimming_bits = 5,
+       .temperature_multiplier = 10,
+       .temperature_divider = 32,
 };
 
 static const struct meson_sar_adc_param meson_sar_adc_gxbb_param = {