Lines Matching +full:adc +full:- +full:dev
2 * palmas-adc.c -- TI PALMAS GPADC.
30 #define MOD_NAME "palmas-gpadc"
33 #define PALMAS_GPADC_TRIMINVALID -1
83 * struct palmas_gpadc - the palmas_gpadc structure
97 * This is the palmas_gpadc structure to store run-time information
102 struct device *dev; member
143 static int palmas_disable_auto_conversion(struct palmas_gpadc *adc) in palmas_disable_auto_conversion() argument
147 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_disable_auto_conversion()
152 dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret); in palmas_disable_auto_conversion()
156 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_disable_auto_conversion()
162 dev_err(adc->dev, "AUTO_CTRL update failed: %d\n", ret); in palmas_disable_auto_conversion()
168 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_disable_auto_conversion()
172 dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret); in palmas_disable_auto_conversion()
179 struct palmas_gpadc *adc = data; in palmas_gpadc_irq() local
181 complete(&adc->conv_completion); in palmas_gpadc_irq()
188 struct palmas_gpadc *adc = data; in palmas_gpadc_irq_auto() local
190 dev_dbg(adc->dev, "Threshold interrupt %d occurs\n", irq); in palmas_gpadc_irq_auto()
191 palmas_disable_auto_conversion(adc); in palmas_gpadc_irq_auto()
196 static int palmas_gpadc_start_mask_interrupt(struct palmas_gpadc *adc, in palmas_gpadc_start_mask_interrupt() argument
202 ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE, in palmas_gpadc_start_mask_interrupt()
206 ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE, in palmas_gpadc_start_mask_interrupt()
211 dev_err(adc->dev, "GPADC INT MASK update failed: %d\n", ret); in palmas_gpadc_start_mask_interrupt()
216 static int palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan, in palmas_gpadc_enable() argument
223 val = (adc->extended_delay in palmas_gpadc_enable()
225 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_enable()
229 dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret); in palmas_gpadc_enable()
236 val = (adc->ch0_current in palmas_gpadc_enable()
238 val |= (adc->ch3_current in palmas_gpadc_enable()
241 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_enable()
244 dev_err(adc->dev, in palmas_gpadc_enable()
252 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_enable()
255 dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret); in palmas_gpadc_enable()
259 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_enable()
262 dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret); in palmas_gpadc_enable()
264 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_enable()
268 dev_err(adc->dev, "CTRL1 update failed: %d\n", ret); in palmas_gpadc_enable()
276 static int palmas_gpadc_read_prepare(struct palmas_gpadc *adc, int adc_chan) in palmas_gpadc_read_prepare() argument
280 ret = palmas_gpadc_enable(adc, adc_chan, true); in palmas_gpadc_read_prepare()
284 return palmas_gpadc_start_mask_interrupt(adc, 0); in palmas_gpadc_read_prepare()
287 static void palmas_gpadc_read_done(struct palmas_gpadc *adc, int adc_chan) in palmas_gpadc_read_done() argument
289 palmas_gpadc_start_mask_interrupt(adc, 1); in palmas_gpadc_read_done()
290 palmas_gpadc_enable(adc, adc_chan, false); in palmas_gpadc_read_done()
293 static int palmas_gpadc_calibrate(struct palmas_gpadc *adc, int adc_chan) in palmas_gpadc_calibrate() argument
300 int x1 = adc->adc_info[adc_chan].x1; in palmas_gpadc_calibrate()
301 int x2 = adc->adc_info[adc_chan].x2; in palmas_gpadc_calibrate()
302 int v1 = adc->adc_info[adc_chan].v1; in palmas_gpadc_calibrate()
303 int v2 = adc->adc_info[adc_chan].v2; in palmas_gpadc_calibrate()
305 ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE, in palmas_gpadc_calibrate()
306 adc->adc_info[adc_chan].trim1_reg, &d1); in palmas_gpadc_calibrate()
308 dev_err(adc->dev, "TRIM read failed: %d\n", ret); in palmas_gpadc_calibrate()
312 ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE, in palmas_gpadc_calibrate()
313 adc->adc_info[adc_chan].trim2_reg, &d2); in palmas_gpadc_calibrate()
315 dev_err(adc->dev, "TRIM read failed: %d\n", ret); in palmas_gpadc_calibrate()
320 k = (1000 + (1000 * (d2 - d1)) / (x2 - x1)); in palmas_gpadc_calibrate()
323 gain = ((v2 - v1) * 1000) / (x2 - x1); in palmas_gpadc_calibrate()
325 adc->adc_info[adc_chan].gain_error = k; in palmas_gpadc_calibrate()
326 adc->adc_info[adc_chan].gain = gain; in palmas_gpadc_calibrate()
328 adc->adc_info[adc_chan].offset = (d1 * 1000) - ((k - 1000) * x1); in palmas_gpadc_calibrate()
334 static int palmas_gpadc_start_conversion(struct palmas_gpadc *adc, int adc_chan) in palmas_gpadc_start_conversion() argument
339 init_completion(&adc->conv_completion); in palmas_gpadc_start_conversion()
340 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_start_conversion()
345 dev_err(adc->dev, "SELECT_SW_START write failed: %d\n", ret); in palmas_gpadc_start_conversion()
349 ret = wait_for_completion_timeout(&adc->conv_completion, in palmas_gpadc_start_conversion()
352 dev_err(adc->dev, "conversion not completed\n"); in palmas_gpadc_start_conversion()
353 return -ETIMEDOUT; in palmas_gpadc_start_conversion()
356 ret = palmas_bulk_read(adc->palmas, PALMAS_GPADC_BASE, in palmas_gpadc_start_conversion()
359 dev_err(adc->dev, "SW_CONV0_LSB read failed: %d\n", ret); in palmas_gpadc_start_conversion()
368 static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc, in palmas_gpadc_get_calibrated_code() argument
371 if (!adc->adc_info[adc_chan].is_uncalibrated) in palmas_gpadc_get_calibrated_code()
372 val = (val*1000 - adc->adc_info[adc_chan].offset) / in palmas_gpadc_get_calibrated_code()
373 adc->adc_info[adc_chan].gain_error; in palmas_gpadc_get_calibrated_code()
376 dev_err(adc->dev, "Mismatch with calibration\n"); in palmas_gpadc_get_calibrated_code()
380 val = (val * adc->adc_info[adc_chan].gain) / 1000; in palmas_gpadc_get_calibrated_code()
388 struct palmas_gpadc *adc = iio_priv(indio_dev); in palmas_gpadc_read_raw() local
389 int adc_chan = chan->channel; in palmas_gpadc_read_raw()
393 return -EINVAL; in palmas_gpadc_read_raw()
395 mutex_lock(&indio_dev->mlock); in palmas_gpadc_read_raw()
400 ret = palmas_gpadc_read_prepare(adc, adc_chan); in palmas_gpadc_read_raw()
404 ret = palmas_gpadc_start_conversion(adc, adc_chan); in palmas_gpadc_read_raw()
406 dev_err(adc->dev, in palmas_gpadc_read_raw()
407 "ADC start conversion failed\n"); in palmas_gpadc_read_raw()
413 adc, adc_chan, ret); in palmas_gpadc_read_raw()
421 mutex_unlock(&indio_dev->mlock); in palmas_gpadc_read_raw()
425 palmas_gpadc_read_done(adc, adc_chan); in palmas_gpadc_read_raw()
426 mutex_unlock(&indio_dev->mlock); in palmas_gpadc_read_raw()
467 struct device_node *np = pdev->dev.of_node; in palmas_gpadc_get_adc_dt_data()
472 gp_data = devm_kzalloc(&pdev->dev, sizeof(*gp_data), GFP_KERNEL); in palmas_gpadc_get_adc_dt_data()
474 return -ENOMEM; in palmas_gpadc_get_adc_dt_data()
476 ret = of_property_read_u32(np, "ti,channel0-current-microamp", &pval); in palmas_gpadc_get_adc_dt_data()
478 gp_data->ch0_current = pval; in palmas_gpadc_get_adc_dt_data()
480 ret = of_property_read_u32(np, "ti,channel3-current-microamp", &pval); in palmas_gpadc_get_adc_dt_data()
482 gp_data->ch3_current = pval; in palmas_gpadc_get_adc_dt_data()
484 gp_data->extended_delay = of_property_read_bool(np, in palmas_gpadc_get_adc_dt_data()
485 "ti,enable-extended-delay"); in palmas_gpadc_get_adc_dt_data()
494 struct palmas_gpadc *adc; in palmas_gpadc_probe() local
500 pdata = dev_get_platdata(pdev->dev.parent); in palmas_gpadc_probe()
502 if (pdata && pdata->gpadc_pdata) in palmas_gpadc_probe()
503 gpadc_pdata = pdata->gpadc_pdata; in palmas_gpadc_probe()
505 if (!gpadc_pdata && pdev->dev.of_node) { in palmas_gpadc_probe()
511 return -EINVAL; in palmas_gpadc_probe()
513 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc)); in palmas_gpadc_probe()
515 dev_err(&pdev->dev, "iio_device_alloc failed\n"); in palmas_gpadc_probe()
516 return -ENOMEM; in palmas_gpadc_probe()
519 adc = iio_priv(indio_dev); in palmas_gpadc_probe()
520 adc->dev = &pdev->dev; in palmas_gpadc_probe()
521 adc->palmas = dev_get_drvdata(pdev->dev.parent); in palmas_gpadc_probe()
522 adc->adc_info = palmas_gpadc_info; in palmas_gpadc_probe()
523 init_completion(&adc->conv_completion); in palmas_gpadc_probe()
524 dev_set_drvdata(&pdev->dev, indio_dev); in palmas_gpadc_probe()
526 adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms; in palmas_gpadc_probe()
527 adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ); in palmas_gpadc_probe()
528 if (adc->irq < 0) { in palmas_gpadc_probe()
529 dev_err(adc->dev, in palmas_gpadc_probe()
530 "get virq failed: %d\n", adc->irq); in palmas_gpadc_probe()
531 ret = adc->irq; in palmas_gpadc_probe()
534 ret = request_threaded_irq(adc->irq, NULL, in palmas_gpadc_probe()
536 IRQF_ONESHOT, dev_name(adc->dev), in palmas_gpadc_probe()
537 adc); in palmas_gpadc_probe()
539 dev_err(adc->dev, in palmas_gpadc_probe()
540 "request irq %d failed: %d\n", adc->irq, ret); in palmas_gpadc_probe()
544 if (gpadc_pdata->adc_wakeup1_data) { in palmas_gpadc_probe()
545 memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data, in palmas_gpadc_probe()
546 sizeof(adc->wakeup1_data)); in palmas_gpadc_probe()
547 adc->wakeup1_enable = true; in palmas_gpadc_probe()
548 adc->irq_auto_0 = platform_get_irq(pdev, 1); in palmas_gpadc_probe()
549 ret = request_threaded_irq(adc->irq_auto_0, NULL, in palmas_gpadc_probe()
552 "palmas-adc-auto-0", adc); in palmas_gpadc_probe()
554 dev_err(adc->dev, "request auto0 irq %d failed: %d\n", in palmas_gpadc_probe()
555 adc->irq_auto_0, ret); in palmas_gpadc_probe()
560 if (gpadc_pdata->adc_wakeup2_data) { in palmas_gpadc_probe()
561 memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data, in palmas_gpadc_probe()
562 sizeof(adc->wakeup2_data)); in palmas_gpadc_probe()
563 adc->wakeup2_enable = true; in palmas_gpadc_probe()
564 adc->irq_auto_1 = platform_get_irq(pdev, 2); in palmas_gpadc_probe()
565 ret = request_threaded_irq(adc->irq_auto_1, NULL, in palmas_gpadc_probe()
568 "palmas-adc-auto-1", adc); in palmas_gpadc_probe()
570 dev_err(adc->dev, "request auto1 irq %d failed: %d\n", in palmas_gpadc_probe()
571 adc->irq_auto_1, ret); in palmas_gpadc_probe()
577 if (gpadc_pdata->ch0_current <= 1) in palmas_gpadc_probe()
578 adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0; in palmas_gpadc_probe()
579 else if (gpadc_pdata->ch0_current <= 5) in palmas_gpadc_probe()
580 adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5; in palmas_gpadc_probe()
581 else if (gpadc_pdata->ch0_current <= 15) in palmas_gpadc_probe()
582 adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15; in palmas_gpadc_probe()
584 adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20; in palmas_gpadc_probe()
587 if (gpadc_pdata->ch3_current <= 1) in palmas_gpadc_probe()
588 adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0; in palmas_gpadc_probe()
589 else if (gpadc_pdata->ch3_current <= 10) in palmas_gpadc_probe()
590 adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10; in palmas_gpadc_probe()
591 else if (gpadc_pdata->ch3_current <= 400) in palmas_gpadc_probe()
592 adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400; in palmas_gpadc_probe()
594 adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800; in palmas_gpadc_probe()
596 adc->extended_delay = gpadc_pdata->extended_delay; in palmas_gpadc_probe()
598 indio_dev->name = MOD_NAME; in palmas_gpadc_probe()
599 indio_dev->dev.parent = &pdev->dev; in palmas_gpadc_probe()
600 indio_dev->info = &palmas_gpadc_iio_info; in palmas_gpadc_probe()
601 indio_dev->modes = INDIO_DIRECT_MODE; in palmas_gpadc_probe()
602 indio_dev->channels = palmas_gpadc_iio_channel; in palmas_gpadc_probe()
603 indio_dev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel); in palmas_gpadc_probe()
607 dev_err(adc->dev, "iio_device_register() failed: %d\n", ret); in palmas_gpadc_probe()
611 device_set_wakeup_capable(&pdev->dev, 1); in palmas_gpadc_probe()
613 if (!(adc->adc_info[i].is_uncalibrated)) in palmas_gpadc_probe()
614 palmas_gpadc_calibrate(adc, i); in palmas_gpadc_probe()
617 if (adc->wakeup1_enable || adc->wakeup2_enable) in palmas_gpadc_probe()
618 device_wakeup_enable(&pdev->dev); in palmas_gpadc_probe()
623 if (gpadc_pdata->adc_wakeup2_data) in palmas_gpadc_probe()
624 free_irq(adc->irq_auto_1, adc); in palmas_gpadc_probe()
626 if (gpadc_pdata->adc_wakeup1_data) in palmas_gpadc_probe()
627 free_irq(adc->irq_auto_0, adc); in palmas_gpadc_probe()
629 free_irq(adc->irq, adc); in palmas_gpadc_probe()
636 struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev); in palmas_gpadc_remove()
637 struct palmas_gpadc *adc = iio_priv(indio_dev); in palmas_gpadc_remove() local
639 if (adc->wakeup1_enable || adc->wakeup2_enable) in palmas_gpadc_remove()
640 device_wakeup_disable(&pdev->dev); in palmas_gpadc_remove()
642 free_irq(adc->irq, adc); in palmas_gpadc_remove()
643 if (adc->wakeup1_enable) in palmas_gpadc_remove()
644 free_irq(adc->irq_auto_0, adc); in palmas_gpadc_remove()
645 if (adc->wakeup2_enable) in palmas_gpadc_remove()
646 free_irq(adc->irq_auto_1, adc); in palmas_gpadc_remove()
652 static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc) in palmas_adc_wakeup_configure() argument
660 adc_period = adc->auto_conversion_period; in palmas_adc_wakeup_configure()
666 i--; in palmas_adc_wakeup_configure()
668 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
673 dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret); in palmas_adc_wakeup_configure()
678 if (adc->wakeup1_enable) { in palmas_adc_wakeup_configure()
681 ch0 = adc->wakeup1_data.adc_channel_number; in palmas_adc_wakeup_configure()
683 if (adc->wakeup1_data.adc_high_threshold > 0) { in palmas_adc_wakeup_configure()
684 thres = adc->wakeup1_data.adc_high_threshold; in palmas_adc_wakeup_configure()
687 thres = adc->wakeup1_data.adc_low_threshold; in palmas_adc_wakeup_configure()
691 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
694 dev_err(adc->dev, in palmas_adc_wakeup_configure()
699 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
703 dev_err(adc->dev, in palmas_adc_wakeup_configure()
709 if (adc->wakeup2_enable) { in palmas_adc_wakeup_configure()
712 ch1 = adc->wakeup2_data.adc_channel_number; in palmas_adc_wakeup_configure()
714 if (adc->wakeup2_data.adc_high_threshold > 0) { in palmas_adc_wakeup_configure()
715 thres = adc->wakeup2_data.adc_high_threshold; in palmas_adc_wakeup_configure()
718 thres = adc->wakeup2_data.adc_low_threshold; in palmas_adc_wakeup_configure()
722 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
725 dev_err(adc->dev, in palmas_adc_wakeup_configure()
730 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
734 dev_err(adc->dev, in palmas_adc_wakeup_configure()
740 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
743 dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret); in palmas_adc_wakeup_configure()
747 ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_configure()
752 dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret); in palmas_adc_wakeup_configure()
757 static int palmas_adc_wakeup_reset(struct palmas_gpadc *adc) in palmas_adc_wakeup_reset() argument
761 ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE, in palmas_adc_wakeup_reset()
764 dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret); in palmas_adc_wakeup_reset()
768 ret = palmas_disable_auto_conversion(adc); in palmas_adc_wakeup_reset()
770 dev_err(adc->dev, "Disable auto conversion failed: %d\n", ret); in palmas_adc_wakeup_reset()
775 static int palmas_gpadc_suspend(struct device *dev) in palmas_gpadc_suspend() argument
777 struct iio_dev *indio_dev = dev_get_drvdata(dev); in palmas_gpadc_suspend()
778 struct palmas_gpadc *adc = iio_priv(indio_dev); in palmas_gpadc_suspend() local
779 int wakeup = adc->wakeup1_enable || adc->wakeup2_enable; in palmas_gpadc_suspend()
782 if (!device_may_wakeup(dev) || !wakeup) in palmas_gpadc_suspend()
785 ret = palmas_adc_wakeup_configure(adc); in palmas_gpadc_suspend()
789 if (adc->wakeup1_enable) in palmas_gpadc_suspend()
790 enable_irq_wake(adc->irq_auto_0); in palmas_gpadc_suspend()
792 if (adc->wakeup2_enable) in palmas_gpadc_suspend()
793 enable_irq_wake(adc->irq_auto_1); in palmas_gpadc_suspend()
798 static int palmas_gpadc_resume(struct device *dev) in palmas_gpadc_resume() argument
800 struct iio_dev *indio_dev = dev_get_drvdata(dev); in palmas_gpadc_resume()
801 struct palmas_gpadc *adc = iio_priv(indio_dev); in palmas_gpadc_resume() local
802 int wakeup = adc->wakeup1_enable || adc->wakeup2_enable; in palmas_gpadc_resume()
805 if (!device_may_wakeup(dev) || !wakeup) in palmas_gpadc_resume()
808 ret = palmas_adc_wakeup_reset(adc); in palmas_gpadc_resume()
812 if (adc->wakeup1_enable) in palmas_gpadc_resume()
813 disable_irq_wake(adc->irq_auto_0); in palmas_gpadc_resume()
815 if (adc->wakeup2_enable) in palmas_gpadc_resume()
816 disable_irq_wake(adc->irq_auto_1); in palmas_gpadc_resume()
828 { .compatible = "ti,palmas-gpadc", },
857 MODULE_ALIAS("platform:palmas-gpadc");