Lines Matching +full:0 +full:- +full:1023

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Copyright (C) 2009-2010 Motorola, Inc.
27 #include <linux/mfd/motorola-cpcap.h>
45 #define CPCAP_BIT_ADEN BIT(0) /* Currently unused */
67 #define CPCAP_BIT_TS_M0 BIT(0) /* Currently unused */
86 * struct cpcap_adc_ato - timing settings for cpcap adc
103 * struct cpcap-adc - cpcap adc device driver data
125 * enum cpcap_adc_channel - cpcap adc channels
156 * enum cpcap_adc_timing - cpcap adc timing options
168 * struct cpcap_adc_phasing_tbl - cpcap phasing table
184 * struct cpcap_adc_conversion_tbl - cpcap conversion table
202 * struct cpcap_adc_request - cpcap adc request
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},
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},
249 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 1, 1,
252 IIO_CHAN_INFO_PROCESSED, 0, 2400, 0, 2300, 1023,
255 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 10000, 1023,
258 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 1, 1,
261 IIO_CHAN_INFO_PROCESSED, 0, 2400, 0, 2300, 1023,
264 IIO_CHAN_INFO_PROCESSED, -512, 2, 0, 5000, 1023,
267 IIO_CHAN_INFO_PROCESSED, -512, 2, 0, 5000, 1023,
270 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
275 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
278 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
281 IIO_CHAN_INFO_PROCESSED, 0, 0, 0, 3400, 1023,
284 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
287 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
290 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
293 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
296 IIO_CHAN_INFO_RAW, 0, 0, 0, 1, 1,
302 * REVISIT: Check the duplicate 0x3ff entry in a freezer
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 },
358 CPCAP_CHAN(IIO_TEMP, 0, CPCAP_REG_ADCD0, "battdetb"),
388 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_irq_thread()
394 ddata->done = true; in cpcap_adc_irq_thread()
395 wake_up_interruptible(&ddata->wq_data_avail); in cpcap_adc_irq_thread()
404 unsigned int value = 0; in cpcap_adc_setup_calibrate()
416 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1, in cpcap_adc_setup_calibrate()
427 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_calibrate()
431 0); in cpcap_adc_setup_calibrate()
435 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_calibrate()
441 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_calibrate()
449 error = regmap_read(ddata->reg, CPCAP_REG_ADCC2, &value); in cpcap_adc_setup_calibrate()
455 dev_err(ddata->dev, in cpcap_adc_setup_calibrate()
458 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1, in cpcap_adc_setup_calibrate()
459 CPCAP_BIT_CAL_MODE, 0); in cpcap_adc_setup_calibrate()
474 for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) { in cpcap_adc_calibrate_one()
475 calibration_data[0] = 0; in cpcap_adc_calibrate_one()
476 calibration_data[1] = 0; in cpcap_adc_calibrate_one()
477 cal_data_diff = 0; in cpcap_adc_calibrate_one()
479 error = regmap_read(ddata->reg, calibration_register, in cpcap_adc_calibrate_one()
480 &calibration_data[0]); in cpcap_adc_calibrate_one()
484 error = regmap_read(ddata->reg, calibration_register, in cpcap_adc_calibrate_one()
489 if (calibration_data[0] > calibration_data[1]) in cpcap_adc_calibrate_one()
491 calibration_data[0] - calibration_data[1]; in cpcap_adc_calibrate_one()
494 calibration_data[1] - calibration_data[0]; in cpcap_adc_calibrate_one()
499 (ddata->vendor == CPCAP_VENDOR_TI)) { in cpcap_adc_calibrate_one()
501 ((short)calibration_data[1] * -1) + 512; in cpcap_adc_calibrate_one()
502 dev_dbg(ddata->dev, "ch%i calibration complete: %i\n", in cpcap_adc_calibrate_one()
509 return 0; in cpcap_adc_calibrate_one()
530 return 0; in cpcap_adc_calibrate()
537 const struct cpcap_adc_ato *ato = ddata->ato; in cpcap_adc_setup_bank()
538 unsigned short value1 = 0; in cpcap_adc_setup_bank()
539 unsigned short value2 = 0; in cpcap_adc_setup_bank()
545 switch (req->channel) { in cpcap_adc_setup_bank()
548 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
564 switch (req->timing) { in cpcap_adc_setup_bank()
566 value1 |= ato->ato_in; in cpcap_adc_setup_bank()
567 value1 |= ato->atox_in; in cpcap_adc_setup_bank()
568 value2 |= ato->adc_ps_factor_in; in cpcap_adc_setup_bank()
569 value2 |= ato->atox_ps_factor_in; in cpcap_adc_setup_bank()
572 value1 |= ato->ato_out; in cpcap_adc_setup_bank()
573 value1 |= ato->atox_out; in cpcap_adc_setup_bank()
574 value2 |= ato->adc_ps_factor_out; in cpcap_adc_setup_bank()
575 value2 |= ato->atox_ps_factor_out; in cpcap_adc_setup_bank()
583 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1, in cpcap_adc_setup_bank()
594 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
603 if (req->timing == CPCAP_ADC_TIMING_IMM) { in cpcap_adc_setup_bank()
604 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
610 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
616 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
622 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_setup_bank()
623 CPCAP_BIT_ADTRIG_DIS, 0); in cpcap_adc_setup_bank()
634 req->timing = CPCAP_ADC_TIMING_IMM; in cpcap_adc_start_bank()
635 ddata->done = false; in cpcap_adc_start_bank()
637 for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) { in cpcap_adc_start_bank()
639 error = wait_event_interruptible_timeout(ddata->wq_data_avail, in cpcap_adc_start_bank()
640 ddata->done, in cpcap_adc_start_bank()
642 if (error > 0) in cpcap_adc_start_bank()
643 return 0; in cpcap_adc_start_bank()
645 if (error == 0) { in cpcap_adc_start_bank()
646 error = -ETIMEDOUT; in cpcap_adc_start_bank()
650 if (error < 0) in cpcap_adc_start_bank()
661 error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1, in cpcap_adc_stop_bank()
662 0xffff, in cpcap_adc_stop_bank()
667 return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2, in cpcap_adc_stop_bank()
668 0xffff, in cpcap_adc_stop_bank()
674 const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl; in cpcap_adc_phase()
675 const struct cpcap_adc_phasing_tbl *phase_tbl = req->phase_tbl; in cpcap_adc_phase()
676 int index = req->channel; in cpcap_adc_phase()
679 switch (req->channel) { in cpcap_adc_phase()
682 index = req->bank_index; in cpcap_adc_phase()
683 req->result -= phase_tbl[index].offset; in cpcap_adc_phase()
684 req->result -= CPCAP_FOUR_POINT_TWO_ADC; in cpcap_adc_phase()
685 req->result *= phase_tbl[index].multiplier; in cpcap_adc_phase()
686 if (phase_tbl[index].divider == 0) in cpcap_adc_phase()
688 req->result /= phase_tbl[index].divider; in cpcap_adc_phase()
689 req->result += CPCAP_FOUR_POINT_TWO_ADC; in cpcap_adc_phase()
692 index = req->bank_index; in cpcap_adc_phase()
695 req->result += conv_tbl[index].cal_offset; in cpcap_adc_phase()
696 req->result += conv_tbl[index].align_offset; in cpcap_adc_phase()
697 req->result *= phase_tbl[index].multiplier; in cpcap_adc_phase()
698 if (phase_tbl[index].divider == 0) in cpcap_adc_phase()
700 req->result /= phase_tbl[index].divider; in cpcap_adc_phase()
701 req->result += phase_tbl[index].offset; in cpcap_adc_phase()
705 if (req->result < phase_tbl[index].min) in cpcap_adc_phase()
706 req->result = phase_tbl[index].min; in cpcap_adc_phase()
707 else if (req->result > phase_tbl[index].max) in cpcap_adc_phase()
708 req->result = phase_tbl[index].max; in cpcap_adc_phase()
714 int i, result = 0, alpha; in cpcap_adc_table_to_millicelcius()
716 if (value <= temp_map[CPCAP_MAX_TEMP_LVL - 1][0]) in cpcap_adc_table_to_millicelcius()
717 return temp_map[CPCAP_MAX_TEMP_LVL - 1][1]; in cpcap_adc_table_to_millicelcius()
719 if (value >= temp_map[0][0]) in cpcap_adc_table_to_millicelcius()
720 return temp_map[0][1]; in cpcap_adc_table_to_millicelcius()
722 for (i = 0; i < CPCAP_MAX_TEMP_LVL - 1; i++) { in cpcap_adc_table_to_millicelcius()
723 if ((value <= temp_map[i][0]) && in cpcap_adc_table_to_millicelcius()
724 (value >= temp_map[i + 1][0])) { in cpcap_adc_table_to_millicelcius()
725 if (value == temp_map[i][0]) { in cpcap_adc_table_to_millicelcius()
727 } else if (value == temp_map[i + 1][0]) { in cpcap_adc_table_to_millicelcius()
730 alpha = ((value - temp_map[i][0]) * 1000) / in cpcap_adc_table_to_millicelcius()
731 (temp_map[i + 1][0] - temp_map[i][0]); in cpcap_adc_table_to_millicelcius()
734 ((alpha * (temp_map[i + 1][1] - in cpcap_adc_table_to_millicelcius()
746 const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl; in cpcap_adc_convert()
747 int index = req->channel; in cpcap_adc_convert()
750 switch (req->channel) { in cpcap_adc_convert()
766 if ((req->channel == CPCAP_ADC_AD0) || in cpcap_adc_convert()
767 (req->channel == CPCAP_ADC_AD3)) { in cpcap_adc_convert()
768 req->result = in cpcap_adc_convert()
769 cpcap_adc_table_to_millicelcius(req->result); in cpcap_adc_convert()
775 req->result *= conv_tbl[index].multiplier; in cpcap_adc_convert()
776 if (conv_tbl[index].divider == 0) in cpcap_adc_convert()
778 req->result /= conv_tbl[index].divider; in cpcap_adc_convert()
779 req->result += conv_tbl[index].conv_offset; in cpcap_adc_convert()
791 if (ddata->vendor == CPCAP_VENDOR_TI) { in cpcap_adc_read_bank_scaled()
792 error = regmap_read(ddata->reg, CPCAP_REG_ADCAL1, in cpcap_adc_read_bank_scaled()
797 ((short)calibration_data * -1) + 512; in cpcap_adc_read_bank_scaled()
799 error = regmap_read(ddata->reg, CPCAP_REG_ADCAL2, in cpcap_adc_read_bank_scaled()
804 ((short)calibration_data * -1) + 512; in cpcap_adc_read_bank_scaled()
807 addr = CPCAP_REG_ADCD0 + req->bank_index * 4; in cpcap_adc_read_bank_scaled()
809 error = regmap_read(ddata->reg, addr, &req->result); in cpcap_adc_read_bank_scaled()
813 req->result &= 0x3ff; in cpcap_adc_read_bank_scaled()
817 return 0; in cpcap_adc_read_bank_scaled()
823 req->channel = channel; in cpcap_adc_init_request()
824 req->phase_tbl = bank_phasing; in cpcap_adc_init_request()
825 req->conv_tbl = bank_conversion; in cpcap_adc_init_request()
829 req->bank_index = channel; in cpcap_adc_init_request()
832 req->bank_index = channel - 8; in cpcap_adc_init_request()
835 req->bank_index = CPCAP_ADC_BATTP; in cpcap_adc_init_request()
838 req->bank_index = CPCAP_ADC_BATTI; in cpcap_adc_init_request()
841 return -EINVAL; in cpcap_adc_init_request()
844 return 0; in cpcap_adc_init_request()
852 error = regmap_read(ddata->reg, addr, val); in cpcap_adc_read_st_die_temp()
856 *val -= 282; in cpcap_adc_read_st_die_temp()
860 return 0; in cpcap_adc_read_st_die_temp()
871 error = cpcap_adc_init_request(&req, chan->channel); in cpcap_adc_read()
877 mutex_lock(&ddata->lock); in cpcap_adc_read()
881 error = regmap_read(ddata->reg, chan->address, val); in cpcap_adc_read()
887 mutex_unlock(&ddata->lock); in cpcap_adc_read()
890 mutex_lock(&ddata->lock); in cpcap_adc_read()
894 if ((ddata->vendor == CPCAP_VENDOR_ST) && in cpcap_adc_read()
895 (chan->channel == CPCAP_ADC_AD3)) { in cpcap_adc_read()
897 chan->address, in cpcap_adc_read()
909 mutex_unlock(&ddata->lock); in cpcap_adc_read()
913 return -EINVAL; in cpcap_adc_read()
919 mutex_unlock(&ddata->lock); in cpcap_adc_read()
920 dev_err(ddata->dev, "error reading ADC: %i\n", error); in cpcap_adc_read()
934 .ato_in = 0x0480,
935 .atox_in = 0,
936 .adc_ps_factor_in = 0x0200,
937 .atox_ps_factor_in = 0,
938 .ato_out = 0,
939 .atox_out = 0,
940 .adc_ps_factor_out = 0,
941 .atox_ps_factor_out = 0,
946 .compatible = "motorola,cpcap-adc",
949 .compatible = "motorola,mapphone-cpcap-adc",
962 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*ddata)); in cpcap_adc_probe()
964 dev_err(&pdev->dev, "failed to allocate iio device\n"); in cpcap_adc_probe()
966 return -ENOMEM; in cpcap_adc_probe()
969 ddata->ato = device_get_match_data(&pdev->dev); in cpcap_adc_probe()
970 if (!ddata->ato) in cpcap_adc_probe()
971 return -ENODEV; in cpcap_adc_probe()
972 ddata->dev = &pdev->dev; in cpcap_adc_probe()
974 mutex_init(&ddata->lock); in cpcap_adc_probe()
975 init_waitqueue_head(&ddata->wq_data_avail); in cpcap_adc_probe()
977 indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; in cpcap_adc_probe()
978 indio_dev->channels = cpcap_adc_channels; in cpcap_adc_probe()
979 indio_dev->num_channels = ARRAY_SIZE(cpcap_adc_channels); in cpcap_adc_probe()
980 indio_dev->name = dev_name(&pdev->dev); in cpcap_adc_probe()
981 indio_dev->info = &cpcap_adc_info; in cpcap_adc_probe()
983 ddata->reg = dev_get_regmap(pdev->dev.parent, NULL); in cpcap_adc_probe()
984 if (!ddata->reg) in cpcap_adc_probe()
985 return -ENODEV; in cpcap_adc_probe()
987 error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor); in cpcap_adc_probe()
993 ddata->irq = platform_get_irq_byname(pdev, "adcdone"); in cpcap_adc_probe()
994 if (ddata->irq < 0) in cpcap_adc_probe()
995 return -ENODEV; in cpcap_adc_probe()
997 error = devm_request_threaded_irq(&pdev->dev, ddata->irq, NULL, in cpcap_adc_probe()
1000 "cpcap-adc", indio_dev); in cpcap_adc_probe()
1002 dev_err(&pdev->dev, "could not get irq: %i\n", in cpcap_adc_probe()
1012 dev_info(&pdev->dev, "CPCAP ADC device probed\n"); in cpcap_adc_probe()
1014 return devm_iio_device_register(&pdev->dev, indio_dev); in cpcap_adc_probe()