aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/adc/at91_adc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/adc/at91_adc.c')
-rw-r--r--drivers/iio/adc/at91_adc.c113
1 files changed, 57 insertions, 56 deletions
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
index b6db6a0e09cd..84be63bdf038 100644
--- a/drivers/iio/adc/at91_adc.c
+++ b/drivers/iio/adc/at91_adc.c
@@ -39,6 +39,10 @@
39#define at91_adc_writel(st, reg, val) \ 39#define at91_adc_writel(st, reg, val) \
40 (writel_relaxed(val, st->reg_base + reg)) 40 (writel_relaxed(val, st->reg_base + reg))
41 41
42struct at91_adc_caps {
43 struct at91_adc_reg_desc registers;
44};
45
42struct at91_adc_state { 46struct at91_adc_state {
43 struct clk *adc_clk; 47 struct clk *adc_clk;
44 u16 *buffer; 48 u16 *buffer;
@@ -62,6 +66,7 @@ struct at91_adc_state {
62 u32 res; /* resolution used for convertions */ 66 u32 res; /* resolution used for convertions */
63 bool low_res; /* the resolution corresponds to the lowest one */ 67 bool low_res; /* the resolution corresponds to the lowest one */
64 wait_queue_head_t wq_data_avail; 68 wait_queue_head_t wq_data_avail;
69 struct at91_adc_caps *caps;
65}; 70};
66 71
67static irqreturn_t at91_adc_trigger_handler(int irq, void *p) 72static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
@@ -429,6 +434,8 @@ ret:
429 return ret; 434 return ret;
430} 435}
431 436
437static const struct of_device_id at91_adc_dt_ids[];
438
432static int at91_adc_probe_dt(struct at91_adc_state *st, 439static int at91_adc_probe_dt(struct at91_adc_state *st,
433 struct platform_device *pdev) 440 struct platform_device *pdev)
434{ 441{
@@ -441,6 +448,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
441 if (!node) 448 if (!node)
442 return -EINVAL; 449 return -EINVAL;
443 450
451 st->caps = (struct at91_adc_caps *)
452 of_match_device(at91_adc_dt_ids, &pdev->dev)->data;
453
444 st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers"); 454 st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers");
445 455
446 if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) { 456 if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) {
@@ -481,43 +491,7 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
481 if (ret) 491 if (ret)
482 goto error_ret; 492 goto error_ret;
483 493
484 st->registers = devm_kzalloc(&idev->dev, 494 st->registers = &st->caps->registers;
485 sizeof(struct at91_adc_reg_desc),
486 GFP_KERNEL);
487 if (!st->registers) {
488 dev_err(&idev->dev, "Could not allocate register memory.\n");
489 ret = -ENOMEM;
490 goto error_ret;
491 }
492
493 if (of_property_read_u32(node, "atmel,adc-channel-base", &prop)) {
494 dev_err(&idev->dev, "Missing adc-channel-base property in the DT.\n");
495 ret = -EINVAL;
496 goto error_ret;
497 }
498 st->registers->channel_base = prop;
499
500 if (of_property_read_u32(node, "atmel,adc-drdy-mask", &prop)) {
501 dev_err(&idev->dev, "Missing adc-drdy-mask property in the DT.\n");
502 ret = -EINVAL;
503 goto error_ret;
504 }
505 st->registers->drdy_mask = prop;
506
507 if (of_property_read_u32(node, "atmel,adc-status-register", &prop)) {
508 dev_err(&idev->dev, "Missing adc-status-register property in the DT.\n");
509 ret = -EINVAL;
510 goto error_ret;
511 }
512 st->registers->status_register = prop;
513
514 if (of_property_read_u32(node, "atmel,adc-trigger-register", &prop)) {
515 dev_err(&idev->dev, "Missing adc-trigger-register property in the DT.\n");
516 ret = -EINVAL;
517 goto error_ret;
518 }
519 st->registers->trigger_register = prop;
520
521 st->trigger_number = of_get_child_count(node); 495 st->trigger_number = of_get_child_count(node);
522 st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * 496 st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number *
523 sizeof(struct at91_adc_trigger), 497 sizeof(struct at91_adc_trigger),
@@ -589,11 +563,9 @@ static int at91_adc_probe(struct platform_device *pdev)
589 struct resource *res; 563 struct resource *res;
590 u32 reg; 564 u32 reg;
591 565
592 idev = iio_device_alloc(sizeof(struct at91_adc_state)); 566 idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state));
593 if (idev == NULL) { 567 if (!idev)
594 ret = -ENOMEM; 568 return -ENOMEM;
595 goto error_ret;
596 }
597 569
598 st = iio_priv(idev); 570 st = iio_priv(idev);
599 571
@@ -604,8 +576,7 @@ static int at91_adc_probe(struct platform_device *pdev)
604 576
605 if (ret) { 577 if (ret) {
606 dev_err(&pdev->dev, "No platform data available.\n"); 578 dev_err(&pdev->dev, "No platform data available.\n");
607 ret = -EINVAL; 579 return -EINVAL;
608 goto error_free_device;
609 } 580 }
610 581
611 platform_set_drvdata(pdev, idev); 582 platform_set_drvdata(pdev, idev);
@@ -618,16 +589,14 @@ static int at91_adc_probe(struct platform_device *pdev)
618 st->irq = platform_get_irq(pdev, 0); 589 st->irq = platform_get_irq(pdev, 0);
619 if (st->irq < 0) { 590 if (st->irq < 0) {
620 dev_err(&pdev->dev, "No IRQ ID is designated\n"); 591 dev_err(&pdev->dev, "No IRQ ID is designated\n");
621 ret = -ENODEV; 592 return -ENODEV;
622 goto error_free_device;
623 } 593 }
624 594
625 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 595 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
626 596
627 st->reg_base = devm_ioremap_resource(&pdev->dev, res); 597 st->reg_base = devm_ioremap_resource(&pdev->dev, res);
628 if (IS_ERR(st->reg_base)) { 598 if (IS_ERR(st->reg_base)) {
629 ret = PTR_ERR(st->reg_base); 599 return PTR_ERR(st->reg_base);
630 goto error_free_device;
631 } 600 }
632 601
633 /* 602 /*
@@ -642,7 +611,7 @@ static int at91_adc_probe(struct platform_device *pdev)
642 idev); 611 idev);
643 if (ret) { 612 if (ret) {
644 dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); 613 dev_err(&pdev->dev, "Failed to allocate IRQ.\n");
645 goto error_free_device; 614 return ret;
646 } 615 }
647 616
648 st->clk = devm_clk_get(&pdev->dev, "adc_clk"); 617 st->clk = devm_clk_get(&pdev->dev, "adc_clk");
@@ -703,8 +672,8 @@ static int at91_adc_probe(struct platform_device *pdev)
703 shtim = round_up((st->sample_hold_time * adc_clk / 672 shtim = round_up((st->sample_hold_time * adc_clk /
704 1000000) - 1, 1); 673 1000000) - 1, 1);
705 674
706 reg = AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL; 675 reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask;
707 reg |= AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP; 676 reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask;
708 if (st->low_res) 677 if (st->low_res)
709 reg |= AT91_ADC_LOWRES; 678 reg |= AT91_ADC_LOWRES;
710 if (st->sleep_mode) 679 if (st->sleep_mode)
@@ -752,9 +721,6 @@ error_disable_clk:
752 clk_disable_unprepare(st->clk); 721 clk_disable_unprepare(st->clk);
753error_free_irq: 722error_free_irq:
754 free_irq(st->irq, idev); 723 free_irq(st->irq, idev);
755error_free_device:
756 iio_device_free(idev);
757error_ret:
758 return ret; 724 return ret;
759} 725}
760 726
@@ -769,14 +735,49 @@ static int at91_adc_remove(struct platform_device *pdev)
769 clk_disable_unprepare(st->adc_clk); 735 clk_disable_unprepare(st->adc_clk);
770 clk_disable_unprepare(st->clk); 736 clk_disable_unprepare(st->clk);
771 free_irq(st->irq, idev); 737 free_irq(st->irq, idev);
772 iio_device_free(idev);
773 738
774 return 0; 739 return 0;
775} 740}
776 741
777#ifdef CONFIG_OF 742#ifdef CONFIG_OF
743static struct at91_adc_caps at91sam9260_caps = {
744 .registers = {
745 .channel_base = AT91_ADC_CHR(0),
746 .drdy_mask = AT91_ADC_DRDY,
747 .status_register = AT91_ADC_SR,
748 .trigger_register = AT91_ADC_TRGR_9260,
749 .mr_prescal_mask = AT91_ADC_PRESCAL_9260,
750 .mr_startup_mask = AT91_ADC_STARTUP_9260,
751 },
752};
753
754static struct at91_adc_caps at91sam9g45_caps = {
755 .registers = {
756 .channel_base = AT91_ADC_CHR(0),
757 .drdy_mask = AT91_ADC_DRDY,
758 .status_register = AT91_ADC_SR,
759 .trigger_register = AT91_ADC_TRGR_9G45,
760 .mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
761 .mr_startup_mask = AT91_ADC_STARTUP_9G45,
762 },
763};
764
765static struct at91_adc_caps at91sam9x5_caps = {
766 .registers = {
767 .channel_base = AT91_ADC_CDR0_9X5,
768 .drdy_mask = AT91_ADC_SR_DRDY_9X5,
769 .status_register = AT91_ADC_SR_9X5,
770 .trigger_register = AT91_ADC_TRGR_9X5,
771 /* prescal mask is same as 9G45 */
772 .mr_prescal_mask = AT91_ADC_PRESCAL_9G45,
773 .mr_startup_mask = AT91_ADC_STARTUP_9X5,
774 },
775};
776
778static const struct of_device_id at91_adc_dt_ids[] = { 777static const struct of_device_id at91_adc_dt_ids[] = {
779 { .compatible = "atmel,at91sam9260-adc" }, 778 { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps },
779 { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps },
780 { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps },
780 {}, 781 {},
781}; 782};
782MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); 783MODULE_DEVICE_TABLE(of, at91_adc_dt_ids);