1075 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2020 Linaro Limited4 *5 * Based on original driver:6 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.7 *8 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.9 */10 11#include <linux/bitfield.h>12#include <linux/iio/adc/qcom-vadc-common.h>13#include <linux/iio/consumer.h>14#include <linux/interrupt.h>15#include <linux/module.h>16#include <linux/of.h>17#include <linux/platform_device.h>18#include <linux/regmap.h>19#include <linux/thermal.h>20 21#include <linux/unaligned.h>22 23#include "../thermal_hwmon.h"24 25/*26 * Thermal monitoring block consists of 8 (ADC_TM5_NUM_CHANNELS) channels. Each27 * channel is programmed to use one of ADC channels for voltage comparison.28 * Voltages are programmed using ADC codes, so we have to convert temp to29 * voltage and then to ADC code value.30 *31 * Configuration of TM channels must match configuration of corresponding ADC32 * channels.33 */34 35#define ADC5_MAX_CHANNEL 0xc036#define ADC_TM5_NUM_CHANNELS 837 38#define ADC_TM5_STATUS_LOW 0x0a39 40#define ADC_TM5_STATUS_HIGH 0x0b41 42#define ADC_TM5_NUM_BTM 0x0f43 44#define ADC_TM5_ADC_DIG_PARAM 0x4245 46#define ADC_TM5_FAST_AVG_CTL (ADC_TM5_ADC_DIG_PARAM + 1)47#define ADC_TM5_FAST_AVG_EN BIT(7)48 49#define ADC_TM5_MEAS_INTERVAL_CTL (ADC_TM5_ADC_DIG_PARAM + 2)50#define ADC_TM5_TIMER1 3 /* 3.9ms */51 52#define ADC_TM5_MEAS_INTERVAL_CTL2 (ADC_TM5_ADC_DIG_PARAM + 3)53#define ADC_TM5_MEAS_INTERVAL_CTL2_MASK 0xf054#define ADC_TM5_TIMER2 10 /* 1 second */55#define ADC_TM5_MEAS_INTERVAL_CTL3_MASK 0xf56#define ADC_TM5_TIMER3 4 /* 4 second */57 58#define ADC_TM_EN_CTL1 0x4659#define ADC_TM_EN BIT(7)60#define ADC_TM_CONV_REQ 0x4761#define ADC_TM_CONV_REQ_EN BIT(7)62 63#define ADC_TM5_M_CHAN_BASE 0x6064 65#define ADC_TM5_M_ADC_CH_SEL_CTL(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 0)66#define ADC_TM5_M_LOW_THR0(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 1)67#define ADC_TM5_M_LOW_THR1(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 2)68#define ADC_TM5_M_HIGH_THR0(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 3)69#define ADC_TM5_M_HIGH_THR1(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 4)70#define ADC_TM5_M_MEAS_INTERVAL_CTL(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 5)71#define ADC_TM5_M_CTL(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 6)72#define ADC_TM5_M_CTL_HW_SETTLE_DELAY_MASK 0xf73#define ADC_TM5_M_CTL_CAL_SEL_MASK 0x3074#define ADC_TM5_M_CTL_CAL_VAL 0x4075#define ADC_TM5_M_EN(n) (ADC_TM5_M_CHAN_BASE + ((n) * 8) + 7)76#define ADC_TM5_M_MEAS_EN BIT(7)77#define ADC_TM5_M_HIGH_THR_INT_EN BIT(1)78#define ADC_TM5_M_LOW_THR_INT_EN BIT(0)79 80#define ADC_TM_GEN2_STATUS1 0x0881#define ADC_TM_GEN2_STATUS_LOW_SET 0x0982#define ADC_TM_GEN2_STATUS_LOW_CLR 0x0a83#define ADC_TM_GEN2_STATUS_HIGH_SET 0x0b84#define ADC_TM_GEN2_STATUS_HIGH_CLR 0x0c85 86#define ADC_TM_GEN2_CFG_HS_SET 0x0d87#define ADC_TM_GEN2_CFG_HS_FLAG BIT(0)88#define ADC_TM_GEN2_CFG_HS_CLR 0x0e89 90#define ADC_TM_GEN2_SID 0x4091 92#define ADC_TM_GEN2_CH_CTL 0x4193#define ADC_TM_GEN2_TM_CH_SEL GENMASK(7, 5)94#define ADC_TM_GEN2_MEAS_INT_SEL GENMASK(3, 2)95 96#define ADC_TM_GEN2_ADC_DIG_PARAM 0x4297#define ADC_TM_GEN2_CTL_CAL_SEL GENMASK(5, 4)98#define ADC_TM_GEN2_CTL_DEC_RATIO_MASK GENMASK(3, 2)99 100#define ADC_TM_GEN2_FAST_AVG_CTL 0x43101#define ADC_TM_GEN2_FAST_AVG_EN BIT(7)102 103#define ADC_TM_GEN2_ADC_CH_SEL_CTL 0x44104 105#define ADC_TM_GEN2_DELAY_CTL 0x45106#define ADC_TM_GEN2_HW_SETTLE_DELAY GENMASK(3, 0)107 108#define ADC_TM_GEN2_EN_CTL1 0x46109#define ADC_TM_GEN2_EN BIT(7)110 111#define ADC_TM_GEN2_CONV_REQ 0x47112#define ADC_TM_GEN2_CONV_REQ_EN BIT(7)113 114#define ADC_TM_GEN2_LOW_THR0 0x49115#define ADC_TM_GEN2_LOW_THR1 0x4a116#define ADC_TM_GEN2_HIGH_THR0 0x4b117#define ADC_TM_GEN2_HIGH_THR1 0x4c118#define ADC_TM_GEN2_LOWER_MASK(n) ((n) & GENMASK(7, 0))119#define ADC_TM_GEN2_UPPER_MASK(n) (((n) & GENMASK(15, 8)) >> 8)120 121#define ADC_TM_GEN2_MEAS_IRQ_EN 0x4d122#define ADC_TM_GEN2_MEAS_EN BIT(7)123#define ADC_TM5_GEN2_HIGH_THR_INT_EN BIT(1)124#define ADC_TM5_GEN2_LOW_THR_INT_EN BIT(0)125 126#define ADC_TM_GEN2_MEAS_INT_LSB 0x50127#define ADC_TM_GEN2_MEAS_INT_MSB 0x51128#define ADC_TM_GEN2_MEAS_INT_MODE 0x52129 130#define ADC_TM_GEN2_Mn_DATA0(n) ((n * 2) + 0xa0)131#define ADC_TM_GEN2_Mn_DATA1(n) ((n * 2) + 0xa1)132#define ADC_TM_GEN2_DATA_SHIFT 8133 134enum adc5_timer_select {135 ADC5_TIMER_SEL_1 = 0,136 ADC5_TIMER_SEL_2,137 ADC5_TIMER_SEL_3,138 ADC5_TIMER_SEL_NONE,139};140 141enum adc5_gen {142 ADC_TM5,143 ADC_TM_HC,144 ADC_TM5_GEN2,145 ADC_TM5_MAX146};147 148enum adc_tm5_cal_method {149 ADC_TM5_NO_CAL = 0,150 ADC_TM5_RATIOMETRIC_CAL,151 ADC_TM5_ABSOLUTE_CAL152};153 154enum adc_tm_gen2_time_select {155 MEAS_INT_50MS = 0,156 MEAS_INT_100MS,157 MEAS_INT_1S,158 MEAS_INT_SET,159 MEAS_INT_NONE,160};161 162struct adc_tm5_chip;163struct adc_tm5_channel;164 165struct adc_tm5_data {166 const u32 full_scale_code_volt;167 unsigned int *decimation;168 unsigned int *hw_settle;169 int (*disable_channel)(struct adc_tm5_channel *channel);170 int (*configure)(struct adc_tm5_channel *channel, int low, int high);171 irqreturn_t (*isr)(int irq, void *data);172 int (*init)(struct adc_tm5_chip *chip);173 char *irq_name;174 int gen;175};176 177/**178 * struct adc_tm5_channel - ADC Thermal Monitoring channel data.179 * @channel: channel number.180 * @adc_channel: corresponding ADC channel number.181 * @cal_method: calibration method.182 * @prescale: channel scaling performed on the input signal.183 * @hw_settle_time: the time between AMUX being configured and the184 * start of conversion.185 * @decimation: sampling rate supported for the channel.186 * @avg_samples: ability to provide single result from the ADC187 * that is an average of multiple measurements.188 * @high_thr_en: channel upper voltage threshold enable state.189 * @low_thr_en: channel lower voltage threshold enable state.190 * @meas_en: recurring measurement enable state191 * @iio: IIO channel instance used by this channel.192 * @chip: ADC TM chip instance.193 * @tzd: thermal zone device used by this channel.194 */195struct adc_tm5_channel {196 unsigned int channel;197 unsigned int adc_channel;198 enum adc_tm5_cal_method cal_method;199 unsigned int prescale;200 unsigned int hw_settle_time;201 unsigned int decimation; /* For Gen2 ADC_TM */202 unsigned int avg_samples; /* For Gen2 ADC_TM */203 bool high_thr_en; /* For Gen2 ADC_TM */204 bool low_thr_en; /* For Gen2 ADC_TM */205 bool meas_en; /* For Gen2 ADC_TM */206 struct iio_channel *iio;207 struct adc_tm5_chip *chip;208 struct thermal_zone_device *tzd;209};210 211/**212 * struct adc_tm5_chip - ADC Thermal Monitoring properties213 * @regmap: SPMI ADC5 Thermal Monitoring peripheral register map field.214 * @dev: SPMI ADC5 device.215 * @data: software configuration data.216 * @channels: array of ADC TM channel data.217 * @nchannels: amount of channels defined/allocated218 * @decimation: sampling rate supported for the channel.219 * Applies to all channels, used only on Gen1 ADC_TM.220 * @avg_samples: ability to provide single result from the ADC221 * that is an average of multiple measurements. Applies to all222 * channels, used only on Gen1 ADC_TM.223 * @base: base address of TM registers.224 * @adc_mutex_lock: ADC_TM mutex lock, used only on Gen2 ADC_TM.225 * It is used to ensure only one ADC channel configuration226 * is done at a time using the shared set of configuration227 * registers.228 */229struct adc_tm5_chip {230 struct regmap *regmap;231 struct device *dev;232 const struct adc_tm5_data *data;233 struct adc_tm5_channel *channels;234 unsigned int nchannels;235 unsigned int decimation;236 unsigned int avg_samples;237 u16 base;238 struct mutex adc_mutex_lock;239};240 241static int adc_tm5_read(struct adc_tm5_chip *adc_tm, u16 offset, u8 *data, int len)242{243 return regmap_bulk_read(adc_tm->regmap, adc_tm->base + offset, data, len);244}245 246static int adc_tm5_write(struct adc_tm5_chip *adc_tm, u16 offset, u8 *data, int len)247{248 return regmap_bulk_write(adc_tm->regmap, adc_tm->base + offset, data, len);249}250 251static int adc_tm5_reg_update(struct adc_tm5_chip *adc_tm, u16 offset, u8 mask, u8 val)252{253 return regmap_write_bits(adc_tm->regmap, adc_tm->base + offset, mask, val);254}255 256static irqreturn_t adc_tm5_isr(int irq, void *data)257{258 struct adc_tm5_chip *chip = data;259 u8 status_low, status_high, ctl;260 int ret, i;261 262 ret = adc_tm5_read(chip, ADC_TM5_STATUS_LOW, &status_low, sizeof(status_low));263 if (unlikely(ret)) {264 dev_err(chip->dev, "read status low failed: %d\n", ret);265 return IRQ_HANDLED;266 }267 268 ret = adc_tm5_read(chip, ADC_TM5_STATUS_HIGH, &status_high, sizeof(status_high));269 if (unlikely(ret)) {270 dev_err(chip->dev, "read status high failed: %d\n", ret);271 return IRQ_HANDLED;272 }273 274 for (i = 0; i < chip->nchannels; i++) {275 bool upper_set = false, lower_set = false;276 unsigned int ch = chip->channels[i].channel;277 278 /* No TZD, we warned at the boot time */279 if (!chip->channels[i].tzd)280 continue;281 282 ret = adc_tm5_read(chip, ADC_TM5_M_EN(ch), &ctl, sizeof(ctl));283 if (unlikely(ret)) {284 dev_err(chip->dev, "ctl read failed: %d, channel %d\n", ret, i);285 continue;286 }287 288 if (!(ctl & ADC_TM5_M_MEAS_EN))289 continue;290 291 lower_set = (status_low & BIT(ch)) &&292 (ctl & ADC_TM5_M_LOW_THR_INT_EN);293 294 upper_set = (status_high & BIT(ch)) &&295 (ctl & ADC_TM5_M_HIGH_THR_INT_EN);296 297 if (upper_set || lower_set)298 thermal_zone_device_update(chip->channels[i].tzd,299 THERMAL_EVENT_UNSPECIFIED);300 }301 302 return IRQ_HANDLED;303}304 305static irqreturn_t adc_tm5_gen2_isr(int irq, void *data)306{307 struct adc_tm5_chip *chip = data;308 u8 status_low, status_high;309 int ret, i;310 311 ret = adc_tm5_read(chip, ADC_TM_GEN2_STATUS_LOW_CLR, &status_low, sizeof(status_low));312 if (ret) {313 dev_err(chip->dev, "read status_low failed: %d\n", ret);314 return IRQ_HANDLED;315 }316 317 ret = adc_tm5_read(chip, ADC_TM_GEN2_STATUS_HIGH_CLR, &status_high, sizeof(status_high));318 if (ret) {319 dev_err(chip->dev, "read status_high failed: %d\n", ret);320 return IRQ_HANDLED;321 }322 323 ret = adc_tm5_write(chip, ADC_TM_GEN2_STATUS_LOW_CLR, &status_low, sizeof(status_low));324 if (ret < 0) {325 dev_err(chip->dev, "clear status low failed with %d\n", ret);326 return IRQ_HANDLED;327 }328 329 ret = adc_tm5_write(chip, ADC_TM_GEN2_STATUS_HIGH_CLR, &status_high, sizeof(status_high));330 if (ret < 0) {331 dev_err(chip->dev, "clear status high failed with %d\n", ret);332 return IRQ_HANDLED;333 }334 335 for (i = 0; i < chip->nchannels; i++) {336 bool upper_set = false, lower_set = false;337 unsigned int ch = chip->channels[i].channel;338 339 /* No TZD, we warned at the boot time */340 if (!chip->channels[i].tzd)341 continue;342 343 if (!chip->channels[i].meas_en)344 continue;345 346 lower_set = (status_low & BIT(ch)) &&347 (chip->channels[i].low_thr_en);348 349 upper_set = (status_high & BIT(ch)) &&350 (chip->channels[i].high_thr_en);351 352 if (upper_set || lower_set)353 thermal_zone_device_update(chip->channels[i].tzd,354 THERMAL_EVENT_UNSPECIFIED);355 }356 357 return IRQ_HANDLED;358}359 360static int adc_tm5_get_temp(struct thermal_zone_device *tz, int *temp)361{362 struct adc_tm5_channel *channel = thermal_zone_device_priv(tz);363 int ret;364 365 if (!channel || !channel->iio)366 return -EINVAL;367 368 ret = iio_read_channel_processed(channel->iio, temp);369 if (ret < 0)370 return ret;371 372 if (ret != IIO_VAL_INT)373 return -EINVAL;374 375 return 0;376}377 378static int adc_tm5_disable_channel(struct adc_tm5_channel *channel)379{380 struct adc_tm5_chip *chip = channel->chip;381 unsigned int reg = ADC_TM5_M_EN(channel->channel);382 383 return adc_tm5_reg_update(chip, reg,384 ADC_TM5_M_MEAS_EN |385 ADC_TM5_M_HIGH_THR_INT_EN |386 ADC_TM5_M_LOW_THR_INT_EN,387 0);388}389 390#define ADC_TM_GEN2_POLL_DELAY_MIN_US 100391#define ADC_TM_GEN2_POLL_DELAY_MAX_US 110392#define ADC_TM_GEN2_POLL_RETRY_COUNT 3393 394static int32_t adc_tm5_gen2_conv_req(struct adc_tm5_chip *chip)395{396 int ret;397 u8 data;398 unsigned int count;399 400 data = ADC_TM_GEN2_EN;401 ret = adc_tm5_write(chip, ADC_TM_GEN2_EN_CTL1, &data, 1);402 if (ret < 0) {403 dev_err(chip->dev, "adc-tm enable failed with %d\n", ret);404 return ret;405 }406 407 data = ADC_TM_GEN2_CFG_HS_FLAG;408 ret = adc_tm5_write(chip, ADC_TM_GEN2_CFG_HS_SET, &data, 1);409 if (ret < 0) {410 dev_err(chip->dev, "adc-tm handshake failed with %d\n", ret);411 return ret;412 }413 414 data = ADC_TM_GEN2_CONV_REQ_EN;415 ret = adc_tm5_write(chip, ADC_TM_GEN2_CONV_REQ, &data, 1);416 if (ret < 0) {417 dev_err(chip->dev, "adc-tm request conversion failed with %d\n", ret);418 return ret;419 }420 421 /*422 * SW sets a handshake bit and waits for PBS to clear it423 * before the next conversion request can be queued.424 */425 426 for (count = 0; count < ADC_TM_GEN2_POLL_RETRY_COUNT; count++) {427 ret = adc_tm5_read(chip, ADC_TM_GEN2_CFG_HS_SET, &data, sizeof(data));428 if (ret < 0) {429 dev_err(chip->dev, "adc-tm read failed with %d\n", ret);430 return ret;431 }432 433 if (!(data & ADC_TM_GEN2_CFG_HS_FLAG))434 return ret;435 usleep_range(ADC_TM_GEN2_POLL_DELAY_MIN_US,436 ADC_TM_GEN2_POLL_DELAY_MAX_US);437 }438 439 dev_err(chip->dev, "adc-tm conversion request handshake timed out\n");440 441 return -ETIMEDOUT;442}443 444static int adc_tm5_gen2_disable_channel(struct adc_tm5_channel *channel)445{446 struct adc_tm5_chip *chip = channel->chip;447 int ret;448 u8 val;449 450 mutex_lock(&chip->adc_mutex_lock);451 452 channel->meas_en = false;453 channel->high_thr_en = false;454 channel->low_thr_en = false;455 456 ret = adc_tm5_read(chip, ADC_TM_GEN2_CH_CTL, &val, sizeof(val));457 if (ret < 0) {458 dev_err(chip->dev, "adc-tm block read failed with %d\n", ret);459 goto disable_fail;460 }461 462 val &= ~ADC_TM_GEN2_TM_CH_SEL;463 val |= FIELD_PREP(ADC_TM_GEN2_TM_CH_SEL, channel->channel);464 465 ret = adc_tm5_write(chip, ADC_TM_GEN2_CH_CTL, &val, 1);466 if (ret < 0) {467 dev_err(chip->dev, "adc-tm channel disable failed with %d\n", ret);468 goto disable_fail;469 }470 471 val = 0;472 ret = adc_tm5_write(chip, ADC_TM_GEN2_MEAS_IRQ_EN, &val, 1);473 if (ret < 0) {474 dev_err(chip->dev, "adc-tm interrupt disable failed with %d\n", ret);475 goto disable_fail;476 }477 478 479 ret = adc_tm5_gen2_conv_req(channel->chip);480 if (ret < 0)481 dev_err(chip->dev, "adc-tm channel configure failed with %d\n", ret);482 483disable_fail:484 mutex_unlock(&chip->adc_mutex_lock);485 return ret;486}487 488static int adc_tm5_enable(struct adc_tm5_chip *chip)489{490 int ret;491 u8 data;492 493 data = ADC_TM_EN;494 ret = adc_tm5_write(chip, ADC_TM_EN_CTL1, &data, sizeof(data));495 if (ret < 0) {496 dev_err(chip->dev, "adc-tm enable failed\n");497 return ret;498 }499 500 data = ADC_TM_CONV_REQ_EN;501 ret = adc_tm5_write(chip, ADC_TM_CONV_REQ, &data, sizeof(data));502 if (ret < 0) {503 dev_err(chip->dev, "adc-tm request conversion failed\n");504 return ret;505 }506 507 return 0;508}509 510static int adc_tm5_configure(struct adc_tm5_channel *channel, int low, int high)511{512 struct adc_tm5_chip *chip = channel->chip;513 u8 buf[8];514 u16 reg = ADC_TM5_M_ADC_CH_SEL_CTL(channel->channel);515 int ret;516 517 ret = adc_tm5_read(chip, reg, buf, sizeof(buf));518 if (ret) {519 dev_err(chip->dev, "channel %d params read failed: %d\n", channel->channel, ret);520 return ret;521 }522 523 buf[0] = channel->adc_channel;524 525 /* High temperature corresponds to low voltage threshold */526 if (high != INT_MAX) {527 u16 adc_code = qcom_adc_tm5_temp_volt_scale(channel->prescale,528 chip->data->full_scale_code_volt, high);529 530 put_unaligned_le16(adc_code, &buf[1]);531 buf[7] |= ADC_TM5_M_LOW_THR_INT_EN;532 } else {533 buf[7] &= ~ADC_TM5_M_LOW_THR_INT_EN;534 }535 536 /* Low temperature corresponds to high voltage threshold */537 if (low != -INT_MAX) {538 u16 adc_code = qcom_adc_tm5_temp_volt_scale(channel->prescale,539 chip->data->full_scale_code_volt, low);540 541 put_unaligned_le16(adc_code, &buf[3]);542 buf[7] |= ADC_TM5_M_HIGH_THR_INT_EN;543 } else {544 buf[7] &= ~ADC_TM5_M_HIGH_THR_INT_EN;545 }546 547 buf[5] = ADC5_TIMER_SEL_2;548 549 /* Set calibration select, hw_settle delay */550 buf[6] &= ~ADC_TM5_M_CTL_HW_SETTLE_DELAY_MASK;551 buf[6] |= FIELD_PREP(ADC_TM5_M_CTL_HW_SETTLE_DELAY_MASK, channel->hw_settle_time);552 buf[6] &= ~ADC_TM5_M_CTL_CAL_SEL_MASK;553 buf[6] |= FIELD_PREP(ADC_TM5_M_CTL_CAL_SEL_MASK, channel->cal_method);554 555 buf[7] |= ADC_TM5_M_MEAS_EN;556 557 ret = adc_tm5_write(chip, reg, buf, sizeof(buf));558 if (ret) {559 dev_err(chip->dev, "channel %d params write failed: %d\n", channel->channel, ret);560 return ret;561 }562 563 return adc_tm5_enable(chip);564}565 566static int adc_tm5_gen2_configure(struct adc_tm5_channel *channel, int low, int high)567{568 struct adc_tm5_chip *chip = channel->chip;569 int ret;570 u8 buf[14];571 u16 adc_code;572 573 mutex_lock(&chip->adc_mutex_lock);574 575 channel->meas_en = true;576 577 ret = adc_tm5_read(chip, ADC_TM_GEN2_SID, buf, sizeof(buf));578 if (ret < 0) {579 dev_err(chip->dev, "adc-tm block read failed with %d\n", ret);580 goto config_fail;581 }582 583 /* Set SID from virtual channel number */584 buf[0] = channel->adc_channel >> 8;585 586 /* Set TM channel number used and measurement interval */587 buf[1] &= ~ADC_TM_GEN2_TM_CH_SEL;588 buf[1] |= FIELD_PREP(ADC_TM_GEN2_TM_CH_SEL, channel->channel);589 buf[1] &= ~ADC_TM_GEN2_MEAS_INT_SEL;590 buf[1] |= FIELD_PREP(ADC_TM_GEN2_MEAS_INT_SEL, MEAS_INT_1S);591 592 buf[2] &= ~ADC_TM_GEN2_CTL_DEC_RATIO_MASK;593 buf[2] |= FIELD_PREP(ADC_TM_GEN2_CTL_DEC_RATIO_MASK, channel->decimation);594 buf[2] &= ~ADC_TM_GEN2_CTL_CAL_SEL;595 buf[2] |= FIELD_PREP(ADC_TM_GEN2_CTL_CAL_SEL, channel->cal_method);596 597 buf[3] = channel->avg_samples | ADC_TM_GEN2_FAST_AVG_EN;598 599 buf[4] = channel->adc_channel & 0xff;600 601 buf[5] = channel->hw_settle_time & ADC_TM_GEN2_HW_SETTLE_DELAY;602 603 /* High temperature corresponds to low voltage threshold */604 if (high != INT_MAX) {605 channel->low_thr_en = true;606 adc_code = qcom_adc_tm5_gen2_temp_res_scale(high);607 put_unaligned_le16(adc_code, &buf[9]);608 } else {609 channel->low_thr_en = false;610 }611 612 /* Low temperature corresponds to high voltage threshold */613 if (low != -INT_MAX) {614 channel->high_thr_en = true;615 adc_code = qcom_adc_tm5_gen2_temp_res_scale(low);616 put_unaligned_le16(adc_code, &buf[11]);617 } else {618 channel->high_thr_en = false;619 }620 621 buf[13] = ADC_TM_GEN2_MEAS_EN;622 if (channel->high_thr_en)623 buf[13] |= ADC_TM5_GEN2_HIGH_THR_INT_EN;624 if (channel->low_thr_en)625 buf[13] |= ADC_TM5_GEN2_LOW_THR_INT_EN;626 627 ret = adc_tm5_write(chip, ADC_TM_GEN2_SID, buf, sizeof(buf));628 if (ret) {629 dev_err(chip->dev, "channel %d params write failed: %d\n", channel->channel, ret);630 goto config_fail;631 }632 633 ret = adc_tm5_gen2_conv_req(channel->chip);634 if (ret < 0)635 dev_err(chip->dev, "adc-tm channel configure failed with %d\n", ret);636 637config_fail:638 mutex_unlock(&chip->adc_mutex_lock);639 return ret;640}641 642static int adc_tm5_set_trips(struct thermal_zone_device *tz, int low, int high)643{644 struct adc_tm5_channel *channel = thermal_zone_device_priv(tz);645 struct adc_tm5_chip *chip;646 int ret;647 648 if (!channel)649 return -EINVAL;650 651 chip = channel->chip;652 dev_dbg(chip->dev, "%d:low(mdegC):%d, high(mdegC):%d\n",653 channel->channel, low, high);654 655 if (high == INT_MAX && low <= -INT_MAX)656 ret = chip->data->disable_channel(channel);657 else658 ret = chip->data->configure(channel, low, high);659 660 return ret;661}662 663static const struct thermal_zone_device_ops adc_tm5_thermal_ops = {664 .get_temp = adc_tm5_get_temp,665 .set_trips = adc_tm5_set_trips,666};667 668static int adc_tm5_register_tzd(struct adc_tm5_chip *adc_tm)669{670 unsigned int i;671 struct thermal_zone_device *tzd;672 673 for (i = 0; i < adc_tm->nchannels; i++) {674 adc_tm->channels[i].chip = adc_tm;675 tzd = devm_thermal_of_zone_register(adc_tm->dev,676 adc_tm->channels[i].channel,677 &adc_tm->channels[i],678 &adc_tm5_thermal_ops);679 if (IS_ERR(tzd)) {680 if (PTR_ERR(tzd) == -ENODEV) {681 dev_dbg(adc_tm->dev, "thermal sensor on channel %d is not used\n",682 adc_tm->channels[i].channel);683 continue;684 }685 686 dev_err(adc_tm->dev, "Error registering TZ zone for channel %d: %ld\n",687 adc_tm->channels[i].channel, PTR_ERR(tzd));688 return PTR_ERR(tzd);689 }690 adc_tm->channels[i].tzd = tzd;691 devm_thermal_add_hwmon_sysfs(adc_tm->dev, tzd);692 }693 694 return 0;695}696 697static int adc_tm_hc_init(struct adc_tm5_chip *chip)698{699 unsigned int i;700 u8 buf[2];701 int ret;702 703 for (i = 0; i < chip->nchannels; i++) {704 if (chip->channels[i].channel >= ADC_TM5_NUM_CHANNELS) {705 dev_err(chip->dev, "Invalid channel %d\n", chip->channels[i].channel);706 return -EINVAL;707 }708 }709 710 buf[0] = chip->decimation;711 buf[1] = chip->avg_samples | ADC_TM5_FAST_AVG_EN;712 713 ret = adc_tm5_write(chip, ADC_TM5_ADC_DIG_PARAM, buf, sizeof(buf));714 if (ret)715 dev_err(chip->dev, "block write failed: %d\n", ret);716 717 return ret;718}719 720static int adc_tm5_init(struct adc_tm5_chip *chip)721{722 u8 buf[4], channels_available;723 int ret;724 unsigned int i;725 726 ret = adc_tm5_read(chip, ADC_TM5_NUM_BTM,727 &channels_available, sizeof(channels_available));728 if (ret) {729 dev_err(chip->dev, "read failed for BTM channels\n");730 return ret;731 }732 733 for (i = 0; i < chip->nchannels; i++) {734 if (chip->channels[i].channel >= channels_available) {735 dev_err(chip->dev, "Invalid channel %d\n", chip->channels[i].channel);736 return -EINVAL;737 }738 }739 740 buf[0] = chip->decimation;741 buf[1] = chip->avg_samples | ADC_TM5_FAST_AVG_EN;742 buf[2] = ADC_TM5_TIMER1;743 buf[3] = FIELD_PREP(ADC_TM5_MEAS_INTERVAL_CTL2_MASK, ADC_TM5_TIMER2) |744 FIELD_PREP(ADC_TM5_MEAS_INTERVAL_CTL3_MASK, ADC_TM5_TIMER3);745 746 ret = adc_tm5_write(chip, ADC_TM5_ADC_DIG_PARAM, buf, sizeof(buf));747 if (ret) {748 dev_err(chip->dev, "block write failed: %d\n", ret);749 return ret;750 }751 752 return ret;753}754 755static int adc_tm5_gen2_init(struct adc_tm5_chip *chip)756{757 u8 channels_available;758 int ret;759 unsigned int i;760 761 ret = adc_tm5_read(chip, ADC_TM5_NUM_BTM,762 &channels_available, sizeof(channels_available));763 if (ret) {764 dev_err(chip->dev, "read failed for BTM channels\n");765 return ret;766 }767 768 for (i = 0; i < chip->nchannels; i++) {769 if (chip->channels[i].channel >= channels_available) {770 dev_err(chip->dev, "Invalid channel %d\n", chip->channels[i].channel);771 return -EINVAL;772 }773 }774 775 mutex_init(&chip->adc_mutex_lock);776 777 return ret;778}779 780static int adc_tm5_get_dt_channel_data(struct adc_tm5_chip *adc_tm,781 struct adc_tm5_channel *channel,782 struct device_node *node)783{784 const char *name = node->name;785 u32 chan, value, adc_channel, varr[2];786 int ret;787 struct device *dev = adc_tm->dev;788 struct of_phandle_args args;789 790 ret = of_property_read_u32(node, "reg", &chan);791 if (ret) {792 dev_err(dev, "%s: invalid channel number %d\n", name, ret);793 return ret;794 }795 796 if (chan >= ADC_TM5_NUM_CHANNELS) {797 dev_err(dev, "%s: channel number too big: %d\n", name, chan);798 return -EINVAL;799 }800 801 channel->channel = chan;802 803 /*804 * We are tied to PMIC's ADC controller, which always use single805 * argument for channel number. So don't bother parsing806 * #io-channel-cells, just enforce cell_count = 1.807 */808 ret = of_parse_phandle_with_fixed_args(node, "io-channels", 1, 0, &args);809 if (ret < 0) {810 dev_err(dev, "%s: error parsing ADC channel number %d: %d\n", name, chan, ret);811 return ret;812 }813 of_node_put(args.np);814 815 if (args.args_count != 1) {816 dev_err(dev, "%s: invalid args count for ADC channel %d\n", name, chan);817 return -EINVAL;818 }819 820 adc_channel = args.args[0];821 if (adc_tm->data->gen == ADC_TM5_GEN2)822 adc_channel &= 0xff;823 824 if (adc_channel >= ADC5_MAX_CHANNEL) {825 dev_err(dev, "%s: invalid ADC channel number %d\n", name, chan);826 return -EINVAL;827 }828 channel->adc_channel = args.args[0];829 830 channel->iio = devm_fwnode_iio_channel_get_by_name(adc_tm->dev,831 of_fwnode_handle(node), NULL);832 if (IS_ERR(channel->iio))833 return dev_err_probe(dev, PTR_ERR(channel->iio), "%s: error getting channel\n",834 name);835 836 ret = of_property_read_u32_array(node, "qcom,pre-scaling", varr, 2);837 if (!ret) {838 ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]);839 if (ret < 0) {840 dev_err(dev, "%s: invalid pre-scaling <%d %d>\n",841 name, varr[0], varr[1]);842 return ret;843 }844 channel->prescale = ret;845 } else {846 /* 1:1 prescale is index 0 */847 channel->prescale = 0;848 }849 850 ret = of_property_read_u32(node, "qcom,hw-settle-time-us", &value);851 if (!ret) {852 ret = qcom_adc5_hw_settle_time_from_dt(value, adc_tm->data->hw_settle);853 if (ret < 0) {854 dev_err(dev, "%s invalid hw-settle-time-us %d us\n",855 name, value);856 return ret;857 }858 channel->hw_settle_time = ret;859 } else {860 channel->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;861 }862 863 if (of_property_read_bool(node, "qcom,ratiometric"))864 channel->cal_method = ADC_TM5_RATIOMETRIC_CAL;865 else866 channel->cal_method = ADC_TM5_ABSOLUTE_CAL;867 868 if (adc_tm->data->gen == ADC_TM5_GEN2) {869 ret = of_property_read_u32(node, "qcom,decimation", &value);870 if (!ret) {871 ret = qcom_adc5_decimation_from_dt(value, adc_tm->data->decimation);872 if (ret < 0) {873 dev_err(dev, "invalid decimation %d\n", value);874 return ret;875 }876 channel->decimation = ret;877 } else {878 channel->decimation = ADC5_DECIMATION_DEFAULT;879 }880 881 ret = of_property_read_u32(node, "qcom,avg-samples", &value);882 if (!ret) {883 ret = qcom_adc5_avg_samples_from_dt(value);884 if (ret < 0) {885 dev_err(dev, "invalid avg-samples %d\n", value);886 return ret;887 }888 channel->avg_samples = ret;889 } else {890 channel->avg_samples = VADC_DEF_AVG_SAMPLES;891 }892 }893 894 return 0;895}896 897static const struct adc_tm5_data adc_tm5_data_pmic = {898 .full_scale_code_volt = 0x70e4,899 .decimation = (unsigned int []) { 250, 420, 840 },900 .hw_settle = (unsigned int []) { 15, 100, 200, 300, 400, 500, 600, 700,901 1000, 2000, 4000, 8000, 16000, 32000,902 64000, 128000 },903 .disable_channel = adc_tm5_disable_channel,904 .configure = adc_tm5_configure,905 .isr = adc_tm5_isr,906 .init = adc_tm5_init,907 .irq_name = "pm-adc-tm5",908 .gen = ADC_TM5,909};910 911static const struct adc_tm5_data adc_tm_hc_data_pmic = {912 .full_scale_code_volt = 0x70e4,913 .decimation = (unsigned int []) { 256, 512, 1024 },914 .hw_settle = (unsigned int []) { 0, 100, 200, 300, 400, 500, 600, 700,915 1000, 2000, 4000, 6000, 8000, 10000 },916 .disable_channel = adc_tm5_disable_channel,917 .configure = adc_tm5_configure,918 .isr = adc_tm5_isr,919 .init = adc_tm_hc_init,920 .irq_name = "pm-adc-tm5",921 .gen = ADC_TM_HC,922};923 924static const struct adc_tm5_data adc_tm5_gen2_data_pmic = {925 .full_scale_code_volt = 0x70e4,926 .decimation = (unsigned int []) { 85, 340, 1360 },927 .hw_settle = (unsigned int []) { 15, 100, 200, 300, 400, 500, 600, 700,928 1000, 2000, 4000, 8000, 16000, 32000,929 64000, 128000 },930 .disable_channel = adc_tm5_gen2_disable_channel,931 .configure = adc_tm5_gen2_configure,932 .isr = adc_tm5_gen2_isr,933 .init = adc_tm5_gen2_init,934 .irq_name = "pm-adc-tm5-gen2",935 .gen = ADC_TM5_GEN2,936};937 938static int adc_tm5_get_dt_data(struct adc_tm5_chip *adc_tm, struct device_node *node)939{940 struct adc_tm5_channel *channels;941 struct device_node *child;942 u32 value;943 int ret;944 struct device *dev = adc_tm->dev;945 946 adc_tm->nchannels = of_get_available_child_count(node);947 if (!adc_tm->nchannels)948 return -EINVAL;949 950 adc_tm->channels = devm_kcalloc(dev, adc_tm->nchannels,951 sizeof(*adc_tm->channels), GFP_KERNEL);952 if (!adc_tm->channels)953 return -ENOMEM;954 955 channels = adc_tm->channels;956 957 adc_tm->data = of_device_get_match_data(dev);958 if (!adc_tm->data)959 adc_tm->data = &adc_tm5_data_pmic;960 961 ret = of_property_read_u32(node, "qcom,decimation", &value);962 if (!ret) {963 ret = qcom_adc5_decimation_from_dt(value, adc_tm->data->decimation);964 if (ret < 0) {965 dev_err(dev, "invalid decimation %d\n", value);966 return ret;967 }968 adc_tm->decimation = ret;969 } else {970 adc_tm->decimation = ADC5_DECIMATION_DEFAULT;971 }972 973 ret = of_property_read_u32(node, "qcom,avg-samples", &value);974 if (!ret) {975 ret = qcom_adc5_avg_samples_from_dt(value);976 if (ret < 0) {977 dev_err(dev, "invalid avg-samples %d\n", value);978 return ret;979 }980 adc_tm->avg_samples = ret;981 } else {982 adc_tm->avg_samples = VADC_DEF_AVG_SAMPLES;983 }984 985 for_each_available_child_of_node(node, child) {986 ret = adc_tm5_get_dt_channel_data(adc_tm, channels, child);987 if (ret) {988 of_node_put(child);989 return ret;990 }991 992 channels++;993 }994 995 return 0;996}997 998static int adc_tm5_probe(struct platform_device *pdev)999{1000 struct device_node *node = pdev->dev.of_node;1001 struct device *dev = &pdev->dev;1002 struct adc_tm5_chip *adc_tm;1003 struct regmap *regmap;1004 int ret, irq;1005 u32 reg;1006 1007 regmap = dev_get_regmap(dev->parent, NULL);1008 if (!regmap)1009 return -ENODEV;1010 1011 ret = of_property_read_u32(node, "reg", ®);1012 if (ret)1013 return ret;1014 1015 adc_tm = devm_kzalloc(&pdev->dev, sizeof(*adc_tm), GFP_KERNEL);1016 if (!adc_tm)1017 return -ENOMEM;1018 1019 adc_tm->regmap = regmap;1020 adc_tm->dev = dev;1021 adc_tm->base = reg;1022 1023 irq = platform_get_irq(pdev, 0);1024 if (irq < 0)1025 return irq;1026 1027 ret = adc_tm5_get_dt_data(adc_tm, node);1028 if (ret)1029 return dev_err_probe(dev, ret, "get dt data failed\n");1030 1031 ret = adc_tm->data->init(adc_tm);1032 if (ret) {1033 dev_err(dev, "adc-tm init failed\n");1034 return ret;1035 }1036 1037 ret = adc_tm5_register_tzd(adc_tm);1038 if (ret) {1039 dev_err(dev, "tzd register failed\n");1040 return ret;1041 }1042 1043 return devm_request_threaded_irq(dev, irq, NULL, adc_tm->data->isr,1044 IRQF_ONESHOT, adc_tm->data->irq_name, adc_tm);1045}1046 1047static const struct of_device_id adc_tm5_match_table[] = {1048 {1049 .compatible = "qcom,spmi-adc-tm5",1050 .data = &adc_tm5_data_pmic,1051 },1052 {1053 .compatible = "qcom,spmi-adc-tm-hc",1054 .data = &adc_tm_hc_data_pmic,1055 },1056 {1057 .compatible = "qcom,spmi-adc-tm5-gen2",1058 .data = &adc_tm5_gen2_data_pmic,1059 },1060 { }1061};1062MODULE_DEVICE_TABLE(of, adc_tm5_match_table);1063 1064static struct platform_driver adc_tm5_driver = {1065 .driver = {1066 .name = "qcom-spmi-adc-tm5",1067 .of_match_table = adc_tm5_match_table,1068 },1069 .probe = adc_tm5_probe,1070};1071module_platform_driver(adc_tm5_driver);1072 1073MODULE_DESCRIPTION("SPMI PMIC Thermal Monitor ADC driver");1074MODULE_LICENSE("GPL v2");1075