Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: dac: ad3552r-hs: add support for internal ramp

The ad3552r can be feeded from the HDL controller by an internally
generated 16bit ramp, useful for debug pourposes. Add debugfs a file
to enable or disable it.

Signed-off-by: Angelo Dureghello <adureghello@baylibre.com>
Link: https://patch.msgid.link/20250409-wip-bl-ad3552r-fixes-v5-5-fb429c3a6515@baylibre.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Angelo Dureghello and committed by
Jonathan Cameron
b1c5d68e ca74d0eb

+156 -6
+156 -6
drivers/iio/dac/ad3552r-hs.c
··· 7 7 */ 8 8 9 9 #include <linux/bitfield.h> 10 + #include <linux/debugfs.h> 10 11 #include <linux/delay.h> 11 12 #include <linux/gpio/consumer.h> 12 13 #include <linux/iio/backend.h> ··· 55 54 struct ad3552r_hs_platform_data *data; 56 55 /* INTERFACE_CONFIG_D register cache, in DDR we cannot read values. */ 57 56 u32 config_d; 57 + /* Protects backend I/O operations from concurrent accesses. */ 58 + struct mutex lock; 59 + }; 60 + 61 + enum ad3552r_sources { 62 + AD3552R_SRC_NORMAL, 63 + AD3552R_SRC_RAMP_16BIT, 64 + }; 65 + 66 + static const char * const dbgfs_attr_source[] = { 67 + [AD3552R_SRC_NORMAL] = "normal", 68 + [AD3552R_SRC_RAMP_16BIT] = "ramp-16bit", 58 69 }; 59 70 60 71 static int ad3552r_hs_reg_read(struct ad3552r_hs_state *st, u32 reg, u32 *val, ··· 76 63 WARN_ON_ONCE(st->config_d & AD3552R_MASK_SPI_CONFIG_DDR); 77 64 78 65 return st->data->bus_reg_read(st->back, reg, val, xfer_size); 66 + } 67 + 68 + static int ad3552r_hs_set_data_source(struct ad3552r_hs_state *st, 69 + enum iio_backend_data_source type) 70 + { 71 + int i, ret; 72 + 73 + for (i = 0; i < st->model_data->num_hw_channels; ++i) { 74 + ret = iio_backend_data_source_set(st->back, i, type); 75 + if (ret) 76 + return ret; 77 + } 78 + 79 + return 0; 79 80 } 80 81 81 82 static int ad3552r_hs_update_reg_bits(struct ad3552r_hs_state *st, u32 reg, ··· 510 483 return st->data->bus_reg_write(st->back, reg, writeval, 1); 511 484 } 512 485 486 + static ssize_t ad3552r_hs_show_data_source(struct file *f, char __user *userbuf, 487 + size_t count, loff_t *ppos) 488 + { 489 + struct ad3552r_hs_state *st = file_inode(f)->i_private; 490 + enum iio_backend_data_source type; 491 + int idx, ret; 492 + 493 + guard(mutex)(&st->lock); 494 + 495 + ret = iio_backend_data_source_get(st->back, 0, &type); 496 + if (ret) 497 + return ret; 498 + 499 + switch (type) { 500 + case IIO_BACKEND_INTERNAL_RAMP_16BIT: 501 + idx = AD3552R_SRC_RAMP_16BIT; 502 + break; 503 + case IIO_BACKEND_EXTERNAL: 504 + idx = AD3552R_SRC_NORMAL; 505 + break; 506 + default: 507 + return -EINVAL; 508 + } 509 + 510 + return simple_read_from_buffer(userbuf, count, ppos, 511 + dbgfs_attr_source[idx], 512 + strlen(dbgfs_attr_source[idx])); 513 + } 514 + 515 + static ssize_t ad3552r_hs_write_data_source(struct file *f, 516 + const char __user *userbuf, 517 + size_t count, loff_t *ppos) 518 + { 519 + struct ad3552r_hs_state *st = file_inode(f)->i_private; 520 + char buf[64]; 521 + int ret, source; 522 + 523 + guard(mutex)(&st->lock); 524 + 525 + ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, 526 + count); 527 + if (ret < 0) 528 + return ret; 529 + 530 + buf[count] = '\0'; 531 + 532 + ret = match_string(dbgfs_attr_source, ARRAY_SIZE(dbgfs_attr_source), 533 + buf); 534 + if (ret < 0) 535 + return ret; 536 + 537 + switch (ret) { 538 + case AD3552R_SRC_RAMP_16BIT: 539 + source = IIO_BACKEND_INTERNAL_RAMP_16BIT; 540 + break; 541 + case AD3552R_SRC_NORMAL: 542 + source = IIO_BACKEND_EXTERNAL; 543 + break; 544 + default: 545 + return -EINVAL; 546 + } 547 + 548 + ret = ad3552r_hs_set_data_source(st, source); 549 + if (ret) 550 + return ret; 551 + 552 + return count; 553 + } 554 + 555 + static ssize_t ad3552r_hs_show_data_source_avail(struct file *f, 556 + char __user *userbuf, 557 + size_t count, loff_t *ppos) 558 + { 559 + ssize_t len = 0; 560 + char buf[128]; 561 + int i; 562 + 563 + for (i = 0; i < ARRAY_SIZE(dbgfs_attr_source); i++) { 564 + len += scnprintf(buf + len, PAGE_SIZE - len, "%s ", 565 + dbgfs_attr_source[i]); 566 + } 567 + buf[len - 1] = '\n'; 568 + 569 + return simple_read_from_buffer(userbuf, count, ppos, buf, len); 570 + } 571 + 572 + static const struct file_operations ad3552r_hs_data_source_fops = { 573 + .owner = THIS_MODULE, 574 + .write = ad3552r_hs_write_data_source, 575 + .read = ad3552r_hs_show_data_source, 576 + }; 577 + 578 + static const struct file_operations ad3552r_hs_data_source_avail_fops = { 579 + .owner = THIS_MODULE, 580 + .read = ad3552r_hs_show_data_source_avail, 581 + }; 582 + 513 583 static int ad3552r_hs_setup(struct ad3552r_hs_state *st) 514 584 { 515 585 u16 id; ··· 674 550 if (ret) 675 551 return ret; 676 552 677 - ret = iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL); 678 - if (ret) 679 - return ret; 680 - 681 - ret = iio_backend_data_source_set(st->back, 1, IIO_BACKEND_EXTERNAL); 553 + ret = ad3552r_hs_set_data_source(st, IIO_BACKEND_EXTERNAL); 682 554 if (ret) 683 555 return ret; 684 556 ··· 781 661 .debugfs_reg_access = &ad3552r_hs_reg_access, 782 662 }; 783 663 664 + static void ad3552r_hs_debugfs_init(struct iio_dev *indio_dev) 665 + { 666 + struct ad3552r_hs_state *st = iio_priv(indio_dev); 667 + struct dentry *d = iio_get_debugfs_dentry(indio_dev); 668 + 669 + if (!IS_ENABLED(CONFIG_DEBUG_FS)) 670 + return; 671 + 672 + d = iio_get_debugfs_dentry(indio_dev); 673 + if (!d) { 674 + dev_warn(st->dev, "can't set debugfs in driver dir\n"); 675 + return; 676 + } 677 + 678 + debugfs_create_file("data_source", 0600, d, st, 679 + &ad3552r_hs_data_source_fops); 680 + debugfs_create_file("data_source_available", 0600, d, st, 681 + &ad3552r_hs_data_source_avail_fops); 682 + } 683 + 784 684 static int ad3552r_hs_probe(struct platform_device *pdev) 785 685 { 786 686 struct ad3552r_hs_state *st; ··· 845 705 if (ret) 846 706 return ret; 847 707 848 - return devm_iio_device_register(&pdev->dev, indio_dev); 708 + ret = devm_iio_device_register(&pdev->dev, indio_dev); 709 + if (ret) 710 + return ret; 711 + 712 + ret = devm_mutex_init(&pdev->dev, &st->lock); 713 + if (ret) 714 + return ret; 715 + 716 + ad3552r_hs_debugfs_init(indio_dev); 717 + 718 + return ret; 849 719 } 850 720 851 721 static const struct of_device_id ad3552r_hs_of_id[] = {