1024 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>4 *5 * Rewritten for Linux IIO framework with some code based on6 * earlier driver found in the Motorola Linux kernel:7 *8 * Copyright (C) 2009-2010 Motorola, Inc.9 */10 11#include <linux/delay.h>12#include <linux/device.h>13#include <linux/err.h>14#include <linux/init.h>15#include <linux/interrupt.h>16#include <linux/kernel.h>17#include <linux/module.h>18#include <linux/mod_devicetable.h>19#include <linux/platform_device.h>20#include <linux/property.h>21#include <linux/regmap.h>22 23#include <linux/iio/buffer.h>24#include <linux/iio/driver.h>25#include <linux/iio/iio.h>26#include <linux/iio/kfifo_buf.h>27#include <linux/mfd/motorola-cpcap.h>28 29/* Register CPCAP_REG_ADCC1 bits */30#define CPCAP_BIT_ADEN_AUTO_CLR BIT(15) /* Currently unused */31#define CPCAP_BIT_CAL_MODE BIT(14) /* Set with BIT_RAND0 */32#define CPCAP_BIT_ADC_CLK_SEL1 BIT(13) /* Currently unused */33#define CPCAP_BIT_ADC_CLK_SEL0 BIT(12) /* Currently unused */34#define CPCAP_BIT_ATOX BIT(11)35#define CPCAP_BIT_ATO3 BIT(10)36#define CPCAP_BIT_ATO2 BIT(9)37#define CPCAP_BIT_ATO1 BIT(8)38#define CPCAP_BIT_ATO0 BIT(7)39#define CPCAP_BIT_ADA2 BIT(6)40#define CPCAP_BIT_ADA1 BIT(5)41#define CPCAP_BIT_ADA0 BIT(4)42#define CPCAP_BIT_AD_SEL1 BIT(3) /* Set for bank1 */43#define CPCAP_BIT_RAND1 BIT(2) /* Set for channel 16 & 17 */44#define CPCAP_BIT_RAND0 BIT(1) /* Set with CAL_MODE */45#define CPCAP_BIT_ADEN BIT(0) /* Currently unused */46 47#define CPCAP_REG_ADCC1_DEFAULTS (CPCAP_BIT_ADEN_AUTO_CLR | \48 CPCAP_BIT_ADC_CLK_SEL0 | \49 CPCAP_BIT_RAND1)50 51/* Register CPCAP_REG_ADCC2 bits */52#define CPCAP_BIT_CAL_FACTOR_ENABLE BIT(15) /* Currently unused */53#define CPCAP_BIT_BATDETB_EN BIT(14) /* Currently unused */54#define CPCAP_BIT_ADTRIG_ONESHOT BIT(13) /* Set for !TIMING_IMM */55#define CPCAP_BIT_ASC BIT(12) /* Set for TIMING_IMM */56#define CPCAP_BIT_ATOX_PS_FACTOR BIT(11)57#define CPCAP_BIT_ADC_PS_FACTOR1 BIT(10)58#define CPCAP_BIT_ADC_PS_FACTOR0 BIT(9)59#define CPCAP_BIT_AD4_SELECT BIT(8) /* Currently unused */60#define CPCAP_BIT_ADC_BUSY BIT(7) /* Currently unused */61#define CPCAP_BIT_THERMBIAS_EN BIT(6) /* Bias for AD0_BATTDETB */62#define CPCAP_BIT_ADTRIG_DIS BIT(5) /* Disable interrupt */63#define CPCAP_BIT_LIADC BIT(4) /* Currently unused */64#define CPCAP_BIT_TS_REFEN BIT(3) /* Currently unused */65#define CPCAP_BIT_TS_M2 BIT(2) /* Currently unused */66#define CPCAP_BIT_TS_M1 BIT(1) /* Currently unused */67#define CPCAP_BIT_TS_M0 BIT(0) /* Currently unused */68 69#define CPCAP_REG_ADCC2_DEFAULTS (CPCAP_BIT_AD4_SELECT | \70 CPCAP_BIT_ADTRIG_DIS | \71 CPCAP_BIT_LIADC | \72 CPCAP_BIT_TS_M2 | \73 CPCAP_BIT_TS_M1)74 75#define CPCAP_MAX_TEMP_LVL 2776#define CPCAP_FOUR_POINT_TWO_ADC 80177#define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD 53078#define ST_ADC_CAL_CHRGI_LOW_THRESHOLD 49479#define ST_ADC_CAL_BATTI_HIGH_THRESHOLD 53080#define ST_ADC_CAL_BATTI_LOW_THRESHOLD 49481#define ST_ADC_CALIBRATE_DIFF_THRESHOLD 382 83#define CPCAP_ADC_MAX_RETRIES 5 /* Calibration */84 85/*86 * struct cpcap_adc_ato - timing settings for cpcap adc87 *88 * Unfortunately no cpcap documentation available, please document when89 * using these.90 */91struct cpcap_adc_ato {92 unsigned short ato_in;93 unsigned short atox_in;94 unsigned short adc_ps_factor_in;95 unsigned short atox_ps_factor_in;96 unsigned short ato_out;97 unsigned short atox_out;98 unsigned short adc_ps_factor_out;99 unsigned short atox_ps_factor_out;100};101 102/**103 * struct cpcap_adc - cpcap adc device driver data104 * @reg: cpcap regmap105 * @dev: struct device106 * @vendor: cpcap vendor107 * @irq: interrupt108 * @lock: mutex109 * @ato: request timings110 * @wq_data_avail: work queue111 * @done: work done112 */113struct cpcap_adc {114 struct regmap *reg;115 struct device *dev;116 u16 vendor;117 int irq;118 struct mutex lock; /* ADC register access lock */119 const struct cpcap_adc_ato *ato;120 wait_queue_head_t wq_data_avail;121 bool done;122};123 124/*125 * enum cpcap_adc_channel - cpcap adc channels126 */127enum cpcap_adc_channel {128 /* Bank0 channels */129 CPCAP_ADC_AD0, /* Battery temperature */130 CPCAP_ADC_BATTP, /* Battery voltage */131 CPCAP_ADC_VBUS, /* USB VBUS voltage */132 CPCAP_ADC_AD3, /* Die temperature when charging */133 CPCAP_ADC_BPLUS_AD4, /* Another battery or system voltage */134 CPCAP_ADC_CHG_ISENSE, /* Calibrated charge current */135 CPCAP_ADC_BATTI, /* Calibrated system current */136 CPCAP_ADC_USB_ID, /* USB OTG ID, unused on droid 4? */137 138 /* Bank1 channels */139 CPCAP_ADC_AD8, /* Seems unused */140 CPCAP_ADC_AD9, /* Seems unused */141 CPCAP_ADC_LICELL, /* Maybe system voltage? Always 3V */142 CPCAP_ADC_HV_BATTP, /* Another battery detection? */143 CPCAP_ADC_TSX1_AD12, /* Seems unused, for touchscreen? */144 CPCAP_ADC_TSX2_AD13, /* Seems unused, for touchscreen? */145 CPCAP_ADC_TSY1_AD14, /* Seems unused, for touchscreen? */146 CPCAP_ADC_TSY2_AD15, /* Seems unused, for touchscreen? */147 148 /* Remuxed channels using bank0 entries */149 CPCAP_ADC_BATTP_PI16, /* Alternative mux mode for BATTP */150 CPCAP_ADC_BATTI_PI17, /* Alternative mux mode for BATTI */151 152 CPCAP_ADC_CHANNEL_NUM,153};154 155/*156 * enum cpcap_adc_timing - cpcap adc timing options157 *158 * CPCAP_ADC_TIMING_IMM seems to be immediate with no timings.159 * Please document when using.160 */161enum cpcap_adc_timing {162 CPCAP_ADC_TIMING_IMM,163 CPCAP_ADC_TIMING_IN,164 CPCAP_ADC_TIMING_OUT,165};166 167/**168 * struct cpcap_adc_phasing_tbl - cpcap phasing table169 * @offset: offset in the phasing table170 * @multiplier: multiplier in the phasing table171 * @divider: divider in the phasing table172 * @min: minimum value173 * @max: maximum value174 */175struct cpcap_adc_phasing_tbl {176 short offset;177 unsigned short multiplier;178 unsigned short divider;179 short min;180 short max;181};182 183/**184 * struct cpcap_adc_conversion_tbl - cpcap conversion table185 * @conv_type: conversion type186 * @align_offset: align offset187 * @conv_offset: conversion offset188 * @cal_offset: calibration offset189 * @multiplier: conversion multiplier190 * @divider: conversion divider191 */192struct cpcap_adc_conversion_tbl {193 enum iio_chan_info_enum conv_type;194 int align_offset;195 int conv_offset;196 int cal_offset;197 int multiplier;198 int divider;199};200 201/**202 * struct cpcap_adc_request - cpcap adc request203 * @channel: request channel204 * @phase_tbl: channel phasing table205 * @conv_tbl: channel conversion table206 * @bank_index: channel index within the bank207 * @timing: timing settings208 * @result: result209 */210struct cpcap_adc_request {211 int channel;212 const struct cpcap_adc_phasing_tbl *phase_tbl;213 const struct cpcap_adc_conversion_tbl *conv_tbl;214 int bank_index;215 enum cpcap_adc_timing timing;216 int result;217};218 219/* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */220static const struct cpcap_adc_phasing_tbl bank_phasing[] = {221 /* Bank0 */222 [CPCAP_ADC_AD0] = {0, 0x80, 0x80, 0, 1023},223 [CPCAP_ADC_BATTP] = {0, 0x80, 0x80, 0, 1023},224 [CPCAP_ADC_VBUS] = {0, 0x80, 0x80, 0, 1023},225 [CPCAP_ADC_AD3] = {0, 0x80, 0x80, 0, 1023},226 [CPCAP_ADC_BPLUS_AD4] = {0, 0x80, 0x80, 0, 1023},227 [CPCAP_ADC_CHG_ISENSE] = {0, 0x80, 0x80, -512, 511},228 [CPCAP_ADC_BATTI] = {0, 0x80, 0x80, -512, 511},229 [CPCAP_ADC_USB_ID] = {0, 0x80, 0x80, 0, 1023},230 231 /* Bank1 */232 [CPCAP_ADC_AD8] = {0, 0x80, 0x80, 0, 1023},233 [CPCAP_ADC_AD9] = {0, 0x80, 0x80, 0, 1023},234 [CPCAP_ADC_LICELL] = {0, 0x80, 0x80, 0, 1023},235 [CPCAP_ADC_HV_BATTP] = {0, 0x80, 0x80, 0, 1023},236 [CPCAP_ADC_TSX1_AD12] = {0, 0x80, 0x80, 0, 1023},237 [CPCAP_ADC_TSX2_AD13] = {0, 0x80, 0x80, 0, 1023},238 [CPCAP_ADC_TSY1_AD14] = {0, 0x80, 0x80, 0, 1023},239 [CPCAP_ADC_TSY2_AD15] = {0, 0x80, 0x80, 0, 1023},240};241 242/*243 * Conversion table for channels. Updated during init based on calibration.244 * Here too channels 16 & 17 use BATTP and BATTI.245 */246static struct cpcap_adc_conversion_tbl bank_conversion[] = {247 /* Bank0 */248 [CPCAP_ADC_AD0] = {249 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 1, 1,250 },251 [CPCAP_ADC_BATTP] = {252 IIO_CHAN_INFO_PROCESSED, 0, 2400, 0, 2300, 1023,253 },254 [CPCAP_ADC_VBUS] = {255 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 10000, 1023,256 },257 [CPCAP_ADC_AD3] = {258 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 1, 1,259 },260 [CPCAP_ADC_BPLUS_AD4] = {261 IIO_CHAN_INFO_PROCESSED, 0, 2400, 0, 2300, 1023,262 },263 [CPCAP_ADC_CHG_ISENSE] = {264 IIO_CHAN_INFO_PROCESSED, -512, 2, 0, 5000, 1023,265 },266 [CPCAP_ADC_BATTI] = {267 IIO_CHAN_INFO_PROCESSED, -512, 2, 0, 5000, 1023,268 },269 [CPCAP_ADC_USB_ID] = {270 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,271 },272 273 /* Bank1 */274 [CPCAP_ADC_AD8] = {275 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,276 },277 [CPCAP_ADC_AD9] = {278 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,279 },280 [CPCAP_ADC_LICELL] = {281 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 3400, 1023,282 },283 [CPCAP_ADC_HV_BATTP] = {284 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,285 },286 [CPCAP_ADC_TSX1_AD12] = {287 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,288 },289 [CPCAP_ADC_TSX2_AD13] = {290 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,291 },292 [CPCAP_ADC_TSY1_AD14] = {293 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,294 },295 [CPCAP_ADC_TSY2_AD15] = {296 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,297 },298};299 300/*301 * Temperature lookup table of register values to milliCelcius.302 * REVISIT: Check the duplicate 0x3ff entry in a freezer303 */304static const int temp_map[CPCAP_MAX_TEMP_LVL][2] = {305 { 0x03ff, -40000 },306 { 0x03ff, -35000 },307 { 0x03ef, -30000 },308 { 0x03b2, -25000 },309 { 0x036c, -20000 },310 { 0x0320, -15000 },311 { 0x02d0, -10000 },312 { 0x027f, -5000 },313 { 0x022f, 0 },314 { 0x01e4, 5000 },315 { 0x019f, 10000 },316 { 0x0161, 15000 },317 { 0x012b, 20000 },318 { 0x00fc, 25000 },319 { 0x00d4, 30000 },320 { 0x00b2, 35000 },321 { 0x0095, 40000 },322 { 0x007d, 45000 },323 { 0x0069, 50000 },324 { 0x0059, 55000 },325 { 0x004b, 60000 },326 { 0x003f, 65000 },327 { 0x0036, 70000 },328 { 0x002e, 75000 },329 { 0x0027, 80000 },330 { 0x0022, 85000 },331 { 0x001d, 90000 },332};333 334#define CPCAP_CHAN(_type, _index, _address, _datasheet_name) { \335 .type = (_type), \336 .address = (_address), \337 .indexed = 1, \338 .channel = (_index), \339 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \340 BIT(IIO_CHAN_INFO_PROCESSED), \341 .scan_index = (_index), \342 .scan_type = { \343 .sign = 'u', \344 .realbits = 10, \345 .storagebits = 16, \346 .endianness = IIO_CPU, \347 }, \348 .datasheet_name = (_datasheet_name), \349}350 351/*352 * The datasheet names are from Motorola mapphone Linux kernel except353 * for the last two which might be uncalibrated charge voltage and354 * current.355 */356static const struct iio_chan_spec cpcap_adc_channels[] = {357 /* Bank0 */358 CPCAP_CHAN(IIO_TEMP, 0, CPCAP_REG_ADCD0, "battdetb"),359 CPCAP_CHAN(IIO_VOLTAGE, 1, CPCAP_REG_ADCD1, "battp"),360 CPCAP_CHAN(IIO_VOLTAGE, 2, CPCAP_REG_ADCD2, "vbus"),361 CPCAP_CHAN(IIO_TEMP, 3, CPCAP_REG_ADCD3, "ad3"),362 CPCAP_CHAN(IIO_VOLTAGE, 4, CPCAP_REG_ADCD4, "ad4"),363 CPCAP_CHAN(IIO_CURRENT, 5, CPCAP_REG_ADCD5, "chg_isense"),364 CPCAP_CHAN(IIO_CURRENT, 6, CPCAP_REG_ADCD6, "batti"),365 CPCAP_CHAN(IIO_VOLTAGE, 7, CPCAP_REG_ADCD7, "usb_id"),366 367 /* Bank1 */368 CPCAP_CHAN(IIO_CURRENT, 8, CPCAP_REG_ADCD0, "ad8"),369 CPCAP_CHAN(IIO_VOLTAGE, 9, CPCAP_REG_ADCD1, "ad9"),370 CPCAP_CHAN(IIO_VOLTAGE, 10, CPCAP_REG_ADCD2, "licell"),371 CPCAP_CHAN(IIO_VOLTAGE, 11, CPCAP_REG_ADCD3, "hv_battp"),372 CPCAP_CHAN(IIO_VOLTAGE, 12, CPCAP_REG_ADCD4, "tsx1_ad12"),373 CPCAP_CHAN(IIO_VOLTAGE, 13, CPCAP_REG_ADCD5, "tsx2_ad13"),374 CPCAP_CHAN(IIO_VOLTAGE, 14, CPCAP_REG_ADCD6, "tsy1_ad14"),375 CPCAP_CHAN(IIO_VOLTAGE, 15, CPCAP_REG_ADCD7, "tsy2_ad15"),376 377 /* There are two registers with multiplexed functionality */378 CPCAP_CHAN(IIO_VOLTAGE, 16, CPCAP_REG_ADCD0, "chg_vsense"),379 CPCAP_CHAN(IIO_CURRENT, 17, CPCAP_REG_ADCD1, "batti2"),380};381 382static irqreturn_t cpcap_adc_irq_thread(int irq, void *data)383{384 struct iio_dev *indio_dev = data;385 struct cpcap_adc *ddata = iio_priv(indio_dev);386 int error;387 388 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2,389 CPCAP_BIT_ADTRIG_DIS);390 if (error)391 return IRQ_NONE;392 393 ddata->done = true;394 wake_up_interruptible(&ddata->wq_data_avail);395 396 return IRQ_HANDLED;397}398 399/* ADC calibration functions */400static void cpcap_adc_setup_calibrate(struct cpcap_adc *ddata,401 enum cpcap_adc_channel chan)402{403 unsigned int value = 0;404 unsigned long timeout = jiffies + msecs_to_jiffies(3000);405 int error;406 407 if ((chan != CPCAP_ADC_CHG_ISENSE) &&408 (chan != CPCAP_ADC_BATTI))409 return;410 411 value |= CPCAP_BIT_CAL_MODE | CPCAP_BIT_RAND0;412 value |= ((chan << 4) &413 (CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 | CPCAP_BIT_ADA0));414 415 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,416 CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX |417 CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 |418 CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 |419 CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 |420 CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 |421 CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0,422 value);423 if (error)424 return;425 426 error = regmap_clear_bits(ddata->reg, CPCAP_REG_ADCC2,427 CPCAP_BIT_ATOX_PS_FACTOR |428 CPCAP_BIT_ADC_PS_FACTOR1 |429 CPCAP_BIT_ADC_PS_FACTOR0);430 if (error)431 return;432 433 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2,434 CPCAP_BIT_ADTRIG_DIS);435 if (error)436 return;437 438 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2, CPCAP_BIT_ASC);439 if (error)440 return;441 442 do {443 schedule_timeout_uninterruptible(1);444 error = regmap_read(ddata->reg, CPCAP_REG_ADCC2, &value);445 if (error)446 return;447 } while ((value & CPCAP_BIT_ASC) && time_before(jiffies, timeout));448 449 if (value & CPCAP_BIT_ASC)450 dev_err(ddata->dev,451 "Timeout waiting for calibration to complete\n");452 453 error = regmap_clear_bits(ddata->reg, CPCAP_REG_ADCC1,454 CPCAP_BIT_CAL_MODE);455 if (error)456 return;457}458 459static int cpcap_adc_calibrate_one(struct cpcap_adc *ddata,460 int channel,461 u16 calibration_register,462 int lower_threshold,463 int upper_threshold)464{465 unsigned int calibration_data[2];466 unsigned short cal_data_diff;467 int i, error;468 469 for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) {470 calibration_data[0] = 0;471 calibration_data[1] = 0;472 473 cpcap_adc_setup_calibrate(ddata, channel);474 error = regmap_read(ddata->reg, calibration_register,475 &calibration_data[0]);476 if (error)477 return error;478 cpcap_adc_setup_calibrate(ddata, channel);479 error = regmap_read(ddata->reg, calibration_register,480 &calibration_data[1]);481 if (error)482 return error;483 484 if (calibration_data[0] > calibration_data[1])485 cal_data_diff =486 calibration_data[0] - calibration_data[1];487 else488 cal_data_diff =489 calibration_data[1] - calibration_data[0];490 491 if (((calibration_data[1] >= lower_threshold) &&492 (calibration_data[1] <= upper_threshold) &&493 (cal_data_diff <= ST_ADC_CALIBRATE_DIFF_THRESHOLD)) ||494 (ddata->vendor == CPCAP_VENDOR_TI)) {495 bank_conversion[channel].cal_offset =496 ((short)calibration_data[1] * -1) + 512;497 dev_dbg(ddata->dev, "ch%i calibration complete: %i\n",498 channel, bank_conversion[channel].cal_offset);499 break;500 }501 usleep_range(5000, 10000);502 }503 504 return 0;505}506 507static int cpcap_adc_calibrate(struct cpcap_adc *ddata)508{509 int error;510 511 error = cpcap_adc_calibrate_one(ddata, CPCAP_ADC_CHG_ISENSE,512 CPCAP_REG_ADCAL1,513 ST_ADC_CAL_CHRGI_LOW_THRESHOLD,514 ST_ADC_CAL_CHRGI_HIGH_THRESHOLD);515 if (error)516 return error;517 518 error = cpcap_adc_calibrate_one(ddata, CPCAP_ADC_BATTI,519 CPCAP_REG_ADCAL2,520 ST_ADC_CAL_BATTI_LOW_THRESHOLD,521 ST_ADC_CAL_BATTI_HIGH_THRESHOLD);522 if (error)523 return error;524 525 return 0;526}527 528/* ADC setup, read and scale functions */529static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,530 struct cpcap_adc_request *req)531{532 const struct cpcap_adc_ato *ato = ddata->ato;533 unsigned short value1 = 0;534 unsigned short value2 = 0;535 int error;536 537 if (!ato)538 return;539 540 switch (req->channel) {541 case CPCAP_ADC_AD0:542 value2 |= CPCAP_BIT_THERMBIAS_EN;543 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,544 CPCAP_BIT_THERMBIAS_EN,545 value2);546 if (error)547 return;548 usleep_range(800, 1000);549 break;550 case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:551 value1 |= CPCAP_BIT_AD_SEL1;552 break;553 case CPCAP_ADC_BATTP_PI16 ... CPCAP_ADC_BATTI_PI17:554 value1 |= CPCAP_BIT_RAND1;555 break;556 default:557 break;558 }559 560 switch (req->timing) {561 case CPCAP_ADC_TIMING_IN:562 value1 |= ato->ato_in;563 value1 |= ato->atox_in;564 value2 |= ato->adc_ps_factor_in;565 value2 |= ato->atox_ps_factor_in;566 break;567 case CPCAP_ADC_TIMING_OUT:568 value1 |= ato->ato_out;569 value1 |= ato->atox_out;570 value2 |= ato->adc_ps_factor_out;571 value2 |= ato->atox_ps_factor_out;572 break;573 574 case CPCAP_ADC_TIMING_IMM:575 default:576 break;577 }578 579 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,580 CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX |581 CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 |582 CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 |583 CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 |584 CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 |585 CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0,586 value1);587 if (error)588 return;589 590 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,591 CPCAP_BIT_ATOX_PS_FACTOR |592 CPCAP_BIT_ADC_PS_FACTOR1 |593 CPCAP_BIT_ADC_PS_FACTOR0 |594 CPCAP_BIT_THERMBIAS_EN,595 value2);596 if (error)597 return;598 599 if (req->timing == CPCAP_ADC_TIMING_IMM) {600 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2,601 CPCAP_BIT_ADTRIG_DIS);602 if (error)603 return;604 605 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2,606 CPCAP_BIT_ASC);607 if (error)608 return;609 } else {610 error = regmap_set_bits(ddata->reg, CPCAP_REG_ADCC2,611 CPCAP_BIT_ADTRIG_ONESHOT);612 if (error)613 return;614 615 error = regmap_clear_bits(ddata->reg, CPCAP_REG_ADCC2,616 CPCAP_BIT_ADTRIG_DIS);617 if (error)618 return;619 }620}621 622static int cpcap_adc_start_bank(struct cpcap_adc *ddata,623 struct cpcap_adc_request *req)624{625 int i, error;626 627 req->timing = CPCAP_ADC_TIMING_IMM;628 ddata->done = false;629 630 for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) {631 cpcap_adc_setup_bank(ddata, req);632 error = wait_event_interruptible_timeout(ddata->wq_data_avail,633 ddata->done,634 msecs_to_jiffies(50));635 if (error > 0)636 return 0;637 638 if (error == 0) {639 error = -ETIMEDOUT;640 continue;641 }642 643 if (error < 0)644 return error;645 }646 647 return error;648}649 650static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)651{652 int error;653 654 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,655 0xffff,656 CPCAP_REG_ADCC1_DEFAULTS);657 if (error)658 return error;659 660 return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,661 0xffff,662 CPCAP_REG_ADCC2_DEFAULTS);663}664 665static void cpcap_adc_phase(struct cpcap_adc_request *req)666{667 const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;668 const struct cpcap_adc_phasing_tbl *phase_tbl = req->phase_tbl;669 int index = req->channel;670 671 /* Remuxed channels 16 and 17 use BATTP and BATTI entries */672 switch (req->channel) {673 case CPCAP_ADC_BATTP:674 case CPCAP_ADC_BATTP_PI16:675 index = req->bank_index;676 req->result -= phase_tbl[index].offset;677 req->result -= CPCAP_FOUR_POINT_TWO_ADC;678 req->result *= phase_tbl[index].multiplier;679 if (phase_tbl[index].divider == 0)680 return;681 req->result /= phase_tbl[index].divider;682 req->result += CPCAP_FOUR_POINT_TWO_ADC;683 break;684 case CPCAP_ADC_BATTI_PI17:685 index = req->bank_index;686 fallthrough;687 default:688 req->result += conv_tbl[index].cal_offset;689 req->result += conv_tbl[index].align_offset;690 req->result *= phase_tbl[index].multiplier;691 if (phase_tbl[index].divider == 0)692 return;693 req->result /= phase_tbl[index].divider;694 req->result += phase_tbl[index].offset;695 break;696 }697 698 if (req->result < phase_tbl[index].min)699 req->result = phase_tbl[index].min;700 else if (req->result > phase_tbl[index].max)701 req->result = phase_tbl[index].max;702}703 704/* Looks up temperatures in a table and calculates averages if needed */705static int cpcap_adc_table_to_millicelcius(unsigned short value)706{707 int i, result = 0, alpha;708 709 if (value <= temp_map[CPCAP_MAX_TEMP_LVL - 1][0])710 return temp_map[CPCAP_MAX_TEMP_LVL - 1][1];711 712 if (value >= temp_map[0][0])713 return temp_map[0][1];714 715 for (i = 0; i < CPCAP_MAX_TEMP_LVL - 1; i++) {716 if ((value <= temp_map[i][0]) &&717 (value >= temp_map[i + 1][0])) {718 if (value == temp_map[i][0]) {719 result = temp_map[i][1];720 } else if (value == temp_map[i + 1][0]) {721 result = temp_map[i + 1][1];722 } else {723 alpha = ((value - temp_map[i][0]) * 1000) /724 (temp_map[i + 1][0] - temp_map[i][0]);725 726 result = temp_map[i][1] +727 ((alpha * (temp_map[i + 1][1] -728 temp_map[i][1])) / 1000);729 }730 break;731 }732 }733 734 return result;735}736 737static void cpcap_adc_convert(struct cpcap_adc_request *req)738{739 const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;740 int index = req->channel;741 742 /* Remuxed channels 16 and 17 use BATTP and BATTI entries */743 switch (req->channel) {744 case CPCAP_ADC_BATTP_PI16:745 index = CPCAP_ADC_BATTP;746 break;747 case CPCAP_ADC_BATTI_PI17:748 index = CPCAP_ADC_BATTI;749 break;750 default:751 break;752 }753 754 /* No conversion for raw channels */755 if (conv_tbl[index].conv_type == IIO_CHAN_INFO_RAW)756 return;757 758 /* Temperatures use a lookup table instead of conversion table */759 if ((req->channel == CPCAP_ADC_AD0) ||760 (req->channel == CPCAP_ADC_AD3)) {761 req->result =762 cpcap_adc_table_to_millicelcius(req->result);763 764 return;765 }766 767 /* All processed channels use a conversion table */768 req->result *= conv_tbl[index].multiplier;769 if (conv_tbl[index].divider == 0)770 return;771 req->result /= conv_tbl[index].divider;772 req->result += conv_tbl[index].conv_offset;773}774 775/*776 * REVISIT: Check if timed sampling can use multiple channels at the777 * same time. If not, replace channel_mask with just channel.778 */779static int cpcap_adc_read_bank_scaled(struct cpcap_adc *ddata,780 struct cpcap_adc_request *req)781{782 int calibration_data, error, addr;783 784 if (ddata->vendor == CPCAP_VENDOR_TI) {785 error = regmap_read(ddata->reg, CPCAP_REG_ADCAL1,786 &calibration_data);787 if (error)788 return error;789 bank_conversion[CPCAP_ADC_CHG_ISENSE].cal_offset =790 ((short)calibration_data * -1) + 512;791 792 error = regmap_read(ddata->reg, CPCAP_REG_ADCAL2,793 &calibration_data);794 if (error)795 return error;796 bank_conversion[CPCAP_ADC_BATTI].cal_offset =797 ((short)calibration_data * -1) + 512;798 }799 800 addr = CPCAP_REG_ADCD0 + req->bank_index * 4;801 802 error = regmap_read(ddata->reg, addr, &req->result);803 if (error)804 return error;805 806 req->result &= 0x3ff;807 cpcap_adc_phase(req);808 cpcap_adc_convert(req);809 810 return 0;811}812 813static int cpcap_adc_init_request(struct cpcap_adc_request *req,814 int channel)815{816 req->channel = channel;817 req->phase_tbl = bank_phasing;818 req->conv_tbl = bank_conversion;819 820 switch (channel) {821 case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:822 req->bank_index = channel;823 break;824 case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:825 req->bank_index = channel - 8;826 break;827 case CPCAP_ADC_BATTP_PI16:828 req->bank_index = CPCAP_ADC_BATTP;829 break;830 case CPCAP_ADC_BATTI_PI17:831 req->bank_index = CPCAP_ADC_BATTI;832 break;833 default:834 return -EINVAL;835 }836 837 return 0;838}839 840static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,841 int addr, int *val)842{843 int error;844 845 error = regmap_read(ddata->reg, addr, val);846 if (error)847 return error;848 849 *val -= 282;850 *val *= 114;851 *val += 25000;852 853 return 0;854}855 856static int cpcap_adc_read(struct iio_dev *indio_dev,857 struct iio_chan_spec const *chan,858 int *val, int *val2, long mask)859{860 struct cpcap_adc *ddata = iio_priv(indio_dev);861 struct cpcap_adc_request req;862 int error;863 864 error = cpcap_adc_init_request(&req, chan->channel);865 if (error)866 return error;867 868 switch (mask) {869 case IIO_CHAN_INFO_RAW:870 mutex_lock(&ddata->lock);871 error = cpcap_adc_start_bank(ddata, &req);872 if (error)873 goto err_unlock;874 error = regmap_read(ddata->reg, chan->address, val);875 if (error)876 goto err_unlock;877 error = cpcap_adc_stop_bank(ddata);878 if (error)879 goto err_unlock;880 mutex_unlock(&ddata->lock);881 break;882 case IIO_CHAN_INFO_PROCESSED:883 mutex_lock(&ddata->lock);884 error = cpcap_adc_start_bank(ddata, &req);885 if (error)886 goto err_unlock;887 if ((ddata->vendor == CPCAP_VENDOR_ST) &&888 (chan->channel == CPCAP_ADC_AD3)) {889 error = cpcap_adc_read_st_die_temp(ddata,890 chan->address,891 &req.result);892 if (error)893 goto err_unlock;894 } else {895 error = cpcap_adc_read_bank_scaled(ddata, &req);896 if (error)897 goto err_unlock;898 }899 error = cpcap_adc_stop_bank(ddata);900 if (error)901 goto err_unlock;902 mutex_unlock(&ddata->lock);903 *val = req.result;904 break;905 default:906 return -EINVAL;907 }908 909 return IIO_VAL_INT;910 911err_unlock:912 mutex_unlock(&ddata->lock);913 dev_err(ddata->dev, "error reading ADC: %i\n", error);914 915 return error;916}917 918static const struct iio_info cpcap_adc_info = {919 .read_raw = &cpcap_adc_read,920};921 922/*923 * Configuration for Motorola mapphone series such as droid 4.924 * Copied from the Motorola mapphone kernel tree.925 */926static const struct cpcap_adc_ato mapphone_adc = {927 .ato_in = 0x0480,928 .atox_in = 0,929 .adc_ps_factor_in = 0x0200,930 .atox_ps_factor_in = 0,931 .ato_out = 0,932 .atox_out = 0,933 .adc_ps_factor_out = 0,934 .atox_ps_factor_out = 0,935};936 937static const struct of_device_id cpcap_adc_id_table[] = {938 {939 .compatible = "motorola,cpcap-adc",940 },941 {942 .compatible = "motorola,mapphone-cpcap-adc",943 .data = &mapphone_adc,944 },945 { /* sentinel */ },946};947MODULE_DEVICE_TABLE(of, cpcap_adc_id_table);948 949static int cpcap_adc_probe(struct platform_device *pdev)950{951 struct cpcap_adc *ddata;952 struct iio_dev *indio_dev;953 int error;954 955 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*ddata));956 if (!indio_dev) {957 dev_err(&pdev->dev, "failed to allocate iio device\n");958 959 return -ENOMEM;960 }961 ddata = iio_priv(indio_dev);962 ddata->ato = device_get_match_data(&pdev->dev);963 if (!ddata->ato)964 return -ENODEV;965 ddata->dev = &pdev->dev;966 967 mutex_init(&ddata->lock);968 init_waitqueue_head(&ddata->wq_data_avail);969 970 indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;971 indio_dev->channels = cpcap_adc_channels;972 indio_dev->num_channels = ARRAY_SIZE(cpcap_adc_channels);973 indio_dev->name = dev_name(&pdev->dev);974 indio_dev->info = &cpcap_adc_info;975 976 ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);977 if (!ddata->reg)978 return -ENODEV;979 980 error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);981 if (error)982 return error;983 984 platform_set_drvdata(pdev, indio_dev);985 986 ddata->irq = platform_get_irq_byname(pdev, "adcdone");987 if (ddata->irq < 0)988 return -ENODEV;989 990 error = devm_request_threaded_irq(&pdev->dev, ddata->irq, NULL,991 cpcap_adc_irq_thread,992 IRQF_TRIGGER_NONE | IRQF_ONESHOT,993 "cpcap-adc", indio_dev);994 if (error) {995 dev_err(&pdev->dev, "could not get irq: %i\n",996 error);997 998 return error;999 }1000 1001 error = cpcap_adc_calibrate(ddata);1002 if (error)1003 return error;1004 1005 dev_info(&pdev->dev, "CPCAP ADC device probed\n");1006 1007 return devm_iio_device_register(&pdev->dev, indio_dev);1008}1009 1010static struct platform_driver cpcap_adc_driver = {1011 .driver = {1012 .name = "cpcap_adc",1013 .of_match_table = cpcap_adc_id_table,1014 },1015 .probe = cpcap_adc_probe,1016};1017 1018module_platform_driver(cpcap_adc_driver);1019 1020MODULE_ALIAS("platform:cpcap_adc");1021MODULE_DESCRIPTION("CPCAP ADC driver");1022MODULE_AUTHOR("Tony Lindgren <tony@atomide.com");1023MODULE_LICENSE("GPL v2");1024