| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * AD9833/AD9834/AD9837/AD9838 SPI DDS driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2010-2011 Analog Devices Inc. |
|---|
| 5 | | - * |
|---|
| 6 | | - * Licensed under the GPL-2. |
|---|
| 7 | 6 | */ |
|---|
| 8 | 7 | |
|---|
| 8 | +#include <linux/clk.h> |
|---|
| 9 | 9 | #include <linux/interrupt.h> |
|---|
| 10 | 10 | #include <linux/workqueue.h> |
|---|
| 11 | 11 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 71 | 71 | struct ad9834_state { |
|---|
| 72 | 72 | struct spi_device *spi; |
|---|
| 73 | 73 | struct regulator *reg; |
|---|
| 74 | | - unsigned int mclk; |
|---|
| 74 | + struct clk *mclk; |
|---|
| 75 | 75 | unsigned short control; |
|---|
| 76 | 76 | unsigned short devid; |
|---|
| 77 | 77 | struct spi_transfer xfer; |
|---|
| .. | .. |
|---|
| 110 | 110 | static int ad9834_write_frequency(struct ad9834_state *st, |
|---|
| 111 | 111 | unsigned long addr, unsigned long fout) |
|---|
| 112 | 112 | { |
|---|
| 113 | + unsigned long clk_freq; |
|---|
| 113 | 114 | unsigned long regval; |
|---|
| 114 | 115 | |
|---|
| 115 | | - if (fout > (st->mclk / 2)) |
|---|
| 116 | + clk_freq = clk_get_rate(st->mclk); |
|---|
| 117 | + |
|---|
| 118 | + if (fout > (clk_freq / 2)) |
|---|
| 116 | 119 | return -EINVAL; |
|---|
| 117 | 120 | |
|---|
| 118 | | - regval = ad9834_calc_freqreg(st->mclk, fout); |
|---|
| 121 | + regval = ad9834_calc_freqreg(clk_freq, fout); |
|---|
| 119 | 122 | |
|---|
| 120 | 123 | st->freq_data[0] = cpu_to_be16(addr | (regval & |
|---|
| 121 | 124 | RES_MASK(AD9834_FREQ_BITS / 2))); |
|---|
| .. | .. |
|---|
| 282 | 285 | struct ad9834_state *st = iio_priv(indio_dev); |
|---|
| 283 | 286 | char *str; |
|---|
| 284 | 287 | |
|---|
| 285 | | - if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) |
|---|
| 288 | + if (st->devid == ID_AD9833 || st->devid == ID_AD9837) |
|---|
| 286 | 289 | str = "sine triangle square"; |
|---|
| 287 | 290 | else if (st->control & AD9834_OPBITEN) |
|---|
| 288 | 291 | str = "sine"; |
|---|
| .. | .. |
|---|
| 389 | 392 | |
|---|
| 390 | 393 | static int ad9834_probe(struct spi_device *spi) |
|---|
| 391 | 394 | { |
|---|
| 392 | | - struct ad9834_platform_data *pdata = dev_get_platdata(&spi->dev); |
|---|
| 393 | 395 | struct ad9834_state *st; |
|---|
| 394 | 396 | struct iio_dev *indio_dev; |
|---|
| 395 | 397 | struct regulator *reg; |
|---|
| 396 | 398 | int ret; |
|---|
| 397 | | - |
|---|
| 398 | | - if (!pdata) { |
|---|
| 399 | | - dev_dbg(&spi->dev, "no platform data?\n"); |
|---|
| 400 | | - return -ENODEV; |
|---|
| 401 | | - } |
|---|
| 402 | 399 | |
|---|
| 403 | 400 | reg = devm_regulator_get(&spi->dev, "avdd"); |
|---|
| 404 | 401 | if (IS_ERR(reg)) |
|---|
| .. | .. |
|---|
| 418 | 415 | spi_set_drvdata(spi, indio_dev); |
|---|
| 419 | 416 | st = iio_priv(indio_dev); |
|---|
| 420 | 417 | mutex_init(&st->lock); |
|---|
| 421 | | - st->mclk = pdata->mclk; |
|---|
| 418 | + st->mclk = devm_clk_get(&spi->dev, NULL); |
|---|
| 419 | + if (IS_ERR(st->mclk)) { |
|---|
| 420 | + ret = PTR_ERR(st->mclk); |
|---|
| 421 | + goto error_disable_reg; |
|---|
| 422 | + } |
|---|
| 423 | + |
|---|
| 424 | + ret = clk_prepare_enable(st->mclk); |
|---|
| 425 | + if (ret) { |
|---|
| 426 | + dev_err(&spi->dev, "Failed to enable master clock\n"); |
|---|
| 427 | + goto error_disable_reg; |
|---|
| 428 | + } |
|---|
| 429 | + |
|---|
| 422 | 430 | st->spi = spi; |
|---|
| 423 | 431 | st->devid = spi_get_device_id(spi)->driver_data; |
|---|
| 424 | 432 | st->reg = reg; |
|---|
| 425 | | - indio_dev->dev.parent = &spi->dev; |
|---|
| 426 | 433 | indio_dev->name = spi_get_device_id(spi)->name; |
|---|
| 427 | 434 | switch (st->devid) { |
|---|
| 428 | 435 | case ID_AD9833: |
|---|
| .. | .. |
|---|
| 454 | 461 | spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); |
|---|
| 455 | 462 | |
|---|
| 456 | 463 | st->control = AD9834_B28 | AD9834_RESET; |
|---|
| 464 | + st->control |= AD9834_DIV2; |
|---|
| 457 | 465 | |
|---|
| 458 | | - if (!pdata->en_div2) |
|---|
| 459 | | - st->control |= AD9834_DIV2; |
|---|
| 460 | | - |
|---|
| 461 | | - if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) |
|---|
| 466 | + if (st->devid == ID_AD9834) |
|---|
| 462 | 467 | st->control |= AD9834_SIGN_PIB; |
|---|
| 463 | 468 | |
|---|
| 464 | 469 | st->data = cpu_to_be16(AD9834_REG_CMD | st->control); |
|---|
| 465 | 470 | ret = spi_sync(st->spi, &st->msg); |
|---|
| 466 | 471 | if (ret) { |
|---|
| 467 | 472 | dev_err(&spi->dev, "device init failed\n"); |
|---|
| 468 | | - goto error_disable_reg; |
|---|
| 473 | + goto error_clock_unprepare; |
|---|
| 469 | 474 | } |
|---|
| 470 | 475 | |
|---|
| 471 | | - ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); |
|---|
| 476 | + ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, 1000000); |
|---|
| 472 | 477 | if (ret) |
|---|
| 473 | | - goto error_disable_reg; |
|---|
| 478 | + goto error_clock_unprepare; |
|---|
| 474 | 479 | |
|---|
| 475 | | - ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); |
|---|
| 480 | + ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, 5000000); |
|---|
| 476 | 481 | if (ret) |
|---|
| 477 | | - goto error_disable_reg; |
|---|
| 482 | + goto error_clock_unprepare; |
|---|
| 478 | 483 | |
|---|
| 479 | | - ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); |
|---|
| 484 | + ret = ad9834_write_phase(st, AD9834_REG_PHASE0, 512); |
|---|
| 480 | 485 | if (ret) |
|---|
| 481 | | - goto error_disable_reg; |
|---|
| 486 | + goto error_clock_unprepare; |
|---|
| 482 | 487 | |
|---|
| 483 | | - ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); |
|---|
| 488 | + ret = ad9834_write_phase(st, AD9834_REG_PHASE1, 1024); |
|---|
| 484 | 489 | if (ret) |
|---|
| 485 | | - goto error_disable_reg; |
|---|
| 490 | + goto error_clock_unprepare; |
|---|
| 486 | 491 | |
|---|
| 487 | 492 | ret = iio_device_register(indio_dev); |
|---|
| 488 | 493 | if (ret) |
|---|
| 489 | | - goto error_disable_reg; |
|---|
| 494 | + goto error_clock_unprepare; |
|---|
| 490 | 495 | |
|---|
| 491 | 496 | return 0; |
|---|
| 492 | | - |
|---|
| 497 | +error_clock_unprepare: |
|---|
| 498 | + clk_disable_unprepare(st->mclk); |
|---|
| 493 | 499 | error_disable_reg: |
|---|
| 494 | 500 | regulator_disable(reg); |
|---|
| 495 | 501 | |
|---|
| .. | .. |
|---|
| 502 | 508 | struct ad9834_state *st = iio_priv(indio_dev); |
|---|
| 503 | 509 | |
|---|
| 504 | 510 | iio_device_unregister(indio_dev); |
|---|
| 511 | + clk_disable_unprepare(st->mclk); |
|---|
| 505 | 512 | regulator_disable(st->reg); |
|---|
| 506 | 513 | |
|---|
| 507 | 514 | return 0; |
|---|
| .. | .. |
|---|
| 516 | 523 | }; |
|---|
| 517 | 524 | MODULE_DEVICE_TABLE(spi, ad9834_id); |
|---|
| 518 | 525 | |
|---|
| 526 | +static const struct of_device_id ad9834_of_match[] = { |
|---|
| 527 | + {.compatible = "adi,ad9833"}, |
|---|
| 528 | + {.compatible = "adi,ad9834"}, |
|---|
| 529 | + {.compatible = "adi,ad9837"}, |
|---|
| 530 | + {.compatible = "adi,ad9838"}, |
|---|
| 531 | + {} |
|---|
| 532 | +}; |
|---|
| 533 | + |
|---|
| 534 | +MODULE_DEVICE_TABLE(of, ad9834_of_match); |
|---|
| 535 | + |
|---|
| 519 | 536 | static struct spi_driver ad9834_driver = { |
|---|
| 520 | 537 | .driver = { |
|---|
| 521 | 538 | .name = "ad9834", |
|---|
| 539 | + .of_match_table = ad9834_of_match |
|---|
| 522 | 540 | }, |
|---|
| 523 | 541 | .probe = ad9834_probe, |
|---|
| 524 | 542 | .remove = ad9834_remove, |
|---|
| .. | .. |
|---|
| 526 | 544 | }; |
|---|
| 527 | 545 | module_spi_driver(ad9834_driver); |
|---|
| 528 | 546 | |
|---|
| 529 | | -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); |
|---|
| 547 | +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); |
|---|
| 530 | 548 | MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS"); |
|---|
| 531 | 549 | MODULE_LICENSE("GPL v2"); |
|---|