162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ADF4377 driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2022 Analog Devices Inc. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/bitfield.h> 962306a36Sopenharmony_ci#include <linux/bits.h> 1062306a36Sopenharmony_ci#include <linux/clk.h> 1162306a36Sopenharmony_ci#include <linux/clkdev.h> 1262306a36Sopenharmony_ci#include <linux/delay.h> 1362306a36Sopenharmony_ci#include <linux/device.h> 1462306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <linux/notifier.h> 1762306a36Sopenharmony_ci#include <linux/property.h> 1862306a36Sopenharmony_ci#include <linux/spi/spi.h> 1962306a36Sopenharmony_ci#include <linux/iio/iio.h> 2062306a36Sopenharmony_ci#include <linux/regmap.h> 2162306a36Sopenharmony_ci#include <linux/units.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include <asm/unaligned.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* ADF4377 REG0000 Map */ 2662306a36Sopenharmony_ci#define ADF4377_0000_SOFT_RESET_R_MSK BIT(7) 2762306a36Sopenharmony_ci#define ADF4377_0000_LSB_FIRST_R_MSK BIT(6) 2862306a36Sopenharmony_ci#define ADF4377_0000_ADDRESS_ASC_R_MSK BIT(5) 2962306a36Sopenharmony_ci#define ADF4377_0000_SDO_ACTIVE_R_MSK BIT(4) 3062306a36Sopenharmony_ci#define ADF4377_0000_SDO_ACTIVE_MSK BIT(3) 3162306a36Sopenharmony_ci#define ADF4377_0000_ADDRESS_ASC_MSK BIT(2) 3262306a36Sopenharmony_ci#define ADF4377_0000_LSB_FIRST_MSK BIT(1) 3362306a36Sopenharmony_ci#define ADF4377_0000_SOFT_RESET_MSK BIT(0) 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* ADF4377 REG0000 Bit Definition */ 3662306a36Sopenharmony_ci#define ADF4377_0000_SDO_ACTIVE_SPI_3W 0x0 3762306a36Sopenharmony_ci#define ADF4377_0000_SDO_ACTIVE_SPI_4W 0x1 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define ADF4377_0000_ADDR_ASC_AUTO_DECR 0x0 4062306a36Sopenharmony_ci#define ADF4377_0000_ADDR_ASC_AUTO_INCR 0x1 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci#define ADF4377_0000_LSB_FIRST_MSB 0x0 4362306a36Sopenharmony_ci#define ADF4377_0000_LSB_FIRST_LSB 0x1 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define ADF4377_0000_SOFT_RESET_N_OP 0x0 4662306a36Sopenharmony_ci#define ADF4377_0000_SOFT_RESET_EN 0x1 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* ADF4377 REG0001 Map */ 4962306a36Sopenharmony_ci#define ADF4377_0001_SINGLE_INSTR_MSK BIT(7) 5062306a36Sopenharmony_ci#define ADF4377_0001_MASTER_RB_CTRL_MSK BIT(5) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci/* ADF4377 REG0003 Bit Definition */ 5362306a36Sopenharmony_ci#define ADF4377_0003_CHIP_TYPE 0x06 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/* ADF4377 REG0004 Bit Definition */ 5662306a36Sopenharmony_ci#define ADF4377_0004_PRODUCT_ID_LSB 0x0005 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* ADF4377 REG0005 Bit Definition */ 5962306a36Sopenharmony_ci#define ADF4377_0005_PRODUCT_ID_MSB 0x0005 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* ADF4377 REG000A Map */ 6262306a36Sopenharmony_ci#define ADF4377_000A_SCRATCHPAD_MSK GENMASK(7, 0) 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* ADF4377 REG000C Bit Definition */ 6562306a36Sopenharmony_ci#define ADF4377_000C_VENDOR_ID_LSB 0x56 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* ADF4377 REG000D Bit Definition */ 6862306a36Sopenharmony_ci#define ADF4377_000D_VENDOR_ID_MSB 0x04 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* ADF4377 REG000F Bit Definition */ 7162306a36Sopenharmony_ci#define ADF4377_000F_R00F_RSV1_MSK GENMASK(7, 0) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci/* ADF4377 REG0010 Map*/ 7462306a36Sopenharmony_ci#define ADF4377_0010_N_INT_LSB_MSK GENMASK(7, 0) 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* ADF4377 REG0011 Map*/ 7762306a36Sopenharmony_ci#define ADF4377_0011_EN_AUTOCAL_MSK BIT(7) 7862306a36Sopenharmony_ci#define ADF4377_0011_EN_RDBLR_MSK BIT(6) 7962306a36Sopenharmony_ci#define ADF4377_0011_DCLK_DIV2_MSK GENMASK(5, 4) 8062306a36Sopenharmony_ci#define ADF4377_0011_N_INT_MSB_MSK GENMASK(3, 0) 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* ADF4377 REG0011 Bit Definition */ 8362306a36Sopenharmony_ci#define ADF4377_0011_DCLK_DIV2_1 0x0 8462306a36Sopenharmony_ci#define ADF4377_0011_DCLK_DIV2_2 0x1 8562306a36Sopenharmony_ci#define ADF4377_0011_DCLK_DIV2_4 0x2 8662306a36Sopenharmony_ci#define ADF4377_0011_DCLK_DIV2_8 0x3 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/* ADF4377 REG0012 Map*/ 8962306a36Sopenharmony_ci#define ADF4377_0012_CLKOUT_DIV_MSK GENMASK(7, 6) 9062306a36Sopenharmony_ci#define ADF4377_0012_R_DIV_MSK GENMASK(5, 0) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/* ADF4377 REG0012 Bit Definition */ 9362306a36Sopenharmony_ci#define ADF4377_0012_CLKOUT_DIV_1 0x0 9462306a36Sopenharmony_ci#define ADF4377_0012_CLKOUT_DIV_2 0x1 9562306a36Sopenharmony_ci#define ADF4377_0012_CLKOUT_DIV_4 0x2 9662306a36Sopenharmony_ci#define ADF4377_0012_CLKOUT_DIV_8 0x3 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* ADF4377 REG0013 Map */ 9962306a36Sopenharmony_ci#define ADF4377_0013_M_VCO_CORE_MSK GENMASK(5, 4) 10062306a36Sopenharmony_ci#define ADF4377_0013_VCO_BIAS_MSK GENMASK(3, 0) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* ADF4377 REG0013 Bit Definition */ 10362306a36Sopenharmony_ci#define ADF4377_0013_M_VCO_0 0x0 10462306a36Sopenharmony_ci#define ADF4377_0013_M_VCO_1 0x1 10562306a36Sopenharmony_ci#define ADF4377_0013_M_VCO_2 0x2 10662306a36Sopenharmony_ci#define ADF4377_0013_M_VCO_3 0x3 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci/* ADF4377 REG0014 Map */ 10962306a36Sopenharmony_ci#define ADF4377_0014_M_VCO_BAND_MSK GENMASK(7, 0) 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci/* ADF4377 REG0015 Map */ 11262306a36Sopenharmony_ci#define ADF4377_0015_BLEED_I_LSB_MSK GENMASK(7, 6) 11362306a36Sopenharmony_ci#define ADF4377_0015_BLEED_POL_MSK BIT(5) 11462306a36Sopenharmony_ci#define ADF4377_0015_EN_BLEED_MSK BIT(4) 11562306a36Sopenharmony_ci#define ADF4377_0015_CP_I_MSK GENMASK(3, 0) 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci/* ADF4377 REG0015 Bit Definition */ 11862306a36Sopenharmony_ci#define ADF4377_CURRENT_SINK 0x0 11962306a36Sopenharmony_ci#define ADF4377_CURRENT_SOURCE 0x1 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci#define ADF4377_0015_CP_0MA7 0x0 12262306a36Sopenharmony_ci#define ADF4377_0015_CP_0MA9 0x1 12362306a36Sopenharmony_ci#define ADF4377_0015_CP_1MA1 0x2 12462306a36Sopenharmony_ci#define ADF4377_0015_CP_1MA3 0x3 12562306a36Sopenharmony_ci#define ADF4377_0015_CP_1MA4 0x4 12662306a36Sopenharmony_ci#define ADF4377_0015_CP_1MA8 0x5 12762306a36Sopenharmony_ci#define ADF4377_0015_CP_2MA2 0x6 12862306a36Sopenharmony_ci#define ADF4377_0015_CP_2MA5 0x7 12962306a36Sopenharmony_ci#define ADF4377_0015_CP_2MA9 0x8 13062306a36Sopenharmony_ci#define ADF4377_0015_CP_3MA6 0x9 13162306a36Sopenharmony_ci#define ADF4377_0015_CP_4MA3 0xA 13262306a36Sopenharmony_ci#define ADF4377_0015_CP_5MA0 0xB 13362306a36Sopenharmony_ci#define ADF4377_0015_CP_5MA7 0xC 13462306a36Sopenharmony_ci#define ADF4377_0015_CP_7MA2 0xD 13562306a36Sopenharmony_ci#define ADF4377_0015_CP_8MA6 0xE 13662306a36Sopenharmony_ci#define ADF4377_0015_CP_10MA1 0xF 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/* ADF4377 REG0016 Map */ 13962306a36Sopenharmony_ci#define ADF4377_0016_BLEED_I_MSB_MSK GENMASK(7, 0) 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* ADF4377 REG0017 Map */ 14262306a36Sopenharmony_ci#define ADF4377_0016_INV_CLKOUT_MSK BIT(7) 14362306a36Sopenharmony_ci#define ADF4377_0016_N_DEL_MSK GENMASK(6, 0) 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/* ADF4377 REG0018 Map */ 14662306a36Sopenharmony_ci#define ADF4377_0018_CMOS_OV_MSK BIT(7) 14762306a36Sopenharmony_ci#define ADF4377_0018_R_DEL_MSK GENMASK(6, 0) 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/* ADF4377 REG0018 Bit Definition */ 15062306a36Sopenharmony_ci#define ADF4377_0018_1V8_LOGIC 0x0 15162306a36Sopenharmony_ci#define ADF4377_0018_3V3_LOGIC 0x1 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci/* ADF4377 REG0019 Map */ 15462306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT2_OP_MSK GENMASK(7, 6) 15562306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT1_OP_MSK GENMASK(5, 4) 15662306a36Sopenharmony_ci#define ADF4377_0019_PD_CLK_MSK BIT(3) 15762306a36Sopenharmony_ci#define ADF4377_0019_PD_RDET_MSK BIT(2) 15862306a36Sopenharmony_ci#define ADF4377_0019_PD_ADC_MSK BIT(1) 15962306a36Sopenharmony_ci#define ADF4377_0019_PD_CALADC_MSK BIT(0) 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci/* ADF4377 REG0019 Bit Definition */ 16262306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT_320MV 0x0 16362306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT_420MV 0x1 16462306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT_530MV 0x2 16562306a36Sopenharmony_ci#define ADF4377_0019_CLKOUT_640MV 0x3 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* ADF4377 REG001A Map */ 16862306a36Sopenharmony_ci#define ADF4377_001A_PD_ALL_MSK BIT(7) 16962306a36Sopenharmony_ci#define ADF4377_001A_PD_RDIV_MSK BIT(6) 17062306a36Sopenharmony_ci#define ADF4377_001A_PD_NDIV_MSK BIT(5) 17162306a36Sopenharmony_ci#define ADF4377_001A_PD_VCO_MSK BIT(4) 17262306a36Sopenharmony_ci#define ADF4377_001A_PD_LD_MSK BIT(3) 17362306a36Sopenharmony_ci#define ADF4377_001A_PD_PFDCP_MSK BIT(2) 17462306a36Sopenharmony_ci#define ADF4377_001A_PD_CLKOUT1_MSK BIT(1) 17562306a36Sopenharmony_ci#define ADF4377_001A_PD_CLKOUT2_MSK BIT(0) 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/* ADF4377 REG001B Map */ 17862306a36Sopenharmony_ci#define ADF4377_001B_EN_LOL_MSK BIT(7) 17962306a36Sopenharmony_ci#define ADF4377_001B_LDWIN_PW_MSK BIT(6) 18062306a36Sopenharmony_ci#define ADF4377_001B_EN_LDWIN_MSK BIT(5) 18162306a36Sopenharmony_ci#define ADF4377_001B_LD_COUNT_MSK GENMASK(4, 0) 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci/* ADF4377 REG001B Bit Definition */ 18462306a36Sopenharmony_ci#define ADF4377_001B_LDWIN_PW_NARROW 0x0 18562306a36Sopenharmony_ci#define ADF4377_001B_LDWIN_PW_WIDE 0x1 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci/* ADF4377 REG001C Map */ 18862306a36Sopenharmony_ci#define ADF4377_001C_EN_DNCLK_MSK BIT(7) 18962306a36Sopenharmony_ci#define ADF4377_001C_EN_DRCLK_MSK BIT(6) 19062306a36Sopenharmony_ci#define ADF4377_001C_RST_LD_MSK BIT(2) 19162306a36Sopenharmony_ci#define ADF4377_001C_R01C_RSV1_MSK BIT(0) 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci/* ADF4377 REG001C Bit Definition */ 19462306a36Sopenharmony_ci#define ADF4377_001C_RST_LD_INACTIVE 0x0 19562306a36Sopenharmony_ci#define ADF4377_001C_RST_LD_ACTIVE 0x1 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci#define ADF4377_001C_R01C_RSV1 0x1 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/* ADF4377 REG001D Map */ 20062306a36Sopenharmony_ci#define ADF4377_001D_MUXOUT_MSK GENMASK(7, 4) 20162306a36Sopenharmony_ci#define ADF4377_001D_EN_CPTEST_MSK BIT(2) 20262306a36Sopenharmony_ci#define ADF4377_001D_CP_DOWN_MSK BIT(1) 20362306a36Sopenharmony_ci#define ADF4377_001D_CP_UP_MSK BIT(0) 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci#define ADF4377_001D_EN_CPTEST_OFF 0x0 20662306a36Sopenharmony_ci#define ADF4377_001D_EN_CPTEST_ON 0x1 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci#define ADF4377_001D_CP_DOWN_OFF 0x0 20962306a36Sopenharmony_ci#define ADF4377_001D_CP_DOWN_ON 0x1 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci#define ADF4377_001D_CP_UP_OFF 0x0 21262306a36Sopenharmony_ci#define ADF4377_001D_CP_UP_ON 0x1 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci/* ADF4377 REG001F Map */ 21562306a36Sopenharmony_ci#define ADF4377_001F_BST_REF_MSK BIT(7) 21662306a36Sopenharmony_ci#define ADF4377_001F_FILT_REF_MSK BIT(6) 21762306a36Sopenharmony_ci#define ADF4377_001F_REF_SEL_MSK BIT(5) 21862306a36Sopenharmony_ci#define ADF4377_001F_R01F_RSV1_MSK GENMASK(4, 0) 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* ADF4377 REG001F Bit Definition */ 22162306a36Sopenharmony_ci#define ADF4377_001F_BST_LARGE_REF_IN 0x0 22262306a36Sopenharmony_ci#define ADF4377_001F_BST_SMALL_REF_IN 0x1 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci#define ADF4377_001F_FILT_REF_OFF 0x0 22562306a36Sopenharmony_ci#define ADF4377_001F_FILT_REF_ON 0x1 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci#define ADF4377_001F_REF_SEL_DMA 0x0 22862306a36Sopenharmony_ci#define ADF4377_001F_REF_SEL_LNA 0x1 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci#define ADF4377_001F_R01F_RSV1 0x7 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci/* ADF4377 REG0020 Map */ 23362306a36Sopenharmony_ci#define ADF4377_0020_RST_SYS_MSK BIT(4) 23462306a36Sopenharmony_ci#define ADF4377_0020_EN_ADC_CLK_MSK BIT(3) 23562306a36Sopenharmony_ci#define ADF4377_0020_R020_RSV1_MSK BIT(0) 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci/* ADF4377 REG0021 Bit Definition */ 23862306a36Sopenharmony_ci#define ADF4377_0021_R021_RSV1 0xD3 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/* ADF4377 REG0022 Bit Definition */ 24162306a36Sopenharmony_ci#define ADF4377_0022_R022_RSV1 0x32 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci/* ADF4377 REG0023 Map */ 24462306a36Sopenharmony_ci#define ADF4377_0023_CAT_CT_SEL BIT(7) 24562306a36Sopenharmony_ci#define ADF4377_0023_R023_RSV1_MSK GENMASK(6, 0) 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* ADF4377 REG0023 Bit Definition */ 24862306a36Sopenharmony_ci#define ADF4377_0023_R023_RSV1 0x18 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci/* ADF4377 REG0024 Map */ 25162306a36Sopenharmony_ci#define ADF4377_0024_DCLK_MODE_MSK BIT(2) 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci/* ADF4377 REG0025 Map */ 25462306a36Sopenharmony_ci#define ADF4377_0025_CLKODIV_DB_MSK BIT(7) 25562306a36Sopenharmony_ci#define ADF4377_0025_DCLK_DB_MSK BIT(6) 25662306a36Sopenharmony_ci#define ADF4377_0025_R025_RSV1_MSK GENMASK(5, 0) 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci/* ADF4377 REG0025 Bit Definition */ 25962306a36Sopenharmony_ci#define ADF4377_0025_R025_RSV1 0x16 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci/* ADF4377 REG0026 Map */ 26262306a36Sopenharmony_ci#define ADF4377_0026_VCO_BAND_DIV_MSK GENMASK(7, 0) 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci/* ADF4377 REG0027 Map */ 26562306a36Sopenharmony_ci#define ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK GENMASK(7, 0) 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci/* ADF4377 REG0028 Map */ 26862306a36Sopenharmony_ci#define ADF4377_0028_O_VCO_DB_MSK BIT(7) 26962306a36Sopenharmony_ci#define ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK GENMASK(6, 0) 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci/* ADF4377 REG0029 Map */ 27262306a36Sopenharmony_ci#define ADF4377_0029_VCO_ALC_TO_LSB_MSK GENMASK(7, 0) 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci/* ADF4377 REG002A Map */ 27562306a36Sopenharmony_ci#define ADF4377_002A_DEL_CTRL_DB_MSK BIT(7) 27662306a36Sopenharmony_ci#define ADF4377_002A_VCO_ALC_TO_MSB_MSK GENMASK(6, 0) 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci/* ADF4377 REG002C Map */ 27962306a36Sopenharmony_ci#define ADF4377_002C_R02C_RSV1 0xC0 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci/* ADF4377 REG002D Map */ 28262306a36Sopenharmony_ci#define ADF4377_002D_ADC_CLK_DIV_MSK GENMASK(7, 0) 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci/* ADF4377 REG002E Map */ 28562306a36Sopenharmony_ci#define ADF4377_002E_EN_ADC_CNV_MSK BIT(7) 28662306a36Sopenharmony_ci#define ADF4377_002E_EN_ADC_MSK BIT(1) 28762306a36Sopenharmony_ci#define ADF4377_002E_ADC_A_CONV_MSK BIT(0) 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci/* ADF4377 REG002E Bit Definition */ 29062306a36Sopenharmony_ci#define ADF4377_002E_ADC_A_CONV_ADC_ST_CNV 0x0 29162306a36Sopenharmony_ci#define ADF4377_002E_ADC_A_CONV_VCO_CALIB 0x1 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci/* ADF4377 REG002F Map */ 29462306a36Sopenharmony_ci#define ADF4377_002F_DCLK_DIV1_MSK GENMASK(1, 0) 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci/* ADF4377 REG002F Bit Definition */ 29762306a36Sopenharmony_ci#define ADF4377_002F_DCLK_DIV1_1 0x0 29862306a36Sopenharmony_ci#define ADF4377_002F_DCLK_DIV1_2 0x1 29962306a36Sopenharmony_ci#define ADF4377_002F_DCLK_DIV1_8 0x2 30062306a36Sopenharmony_ci#define ADF4377_002F_DCLK_DIV1_32 0x3 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci/* ADF4377 REG0031 Bit Definition */ 30362306a36Sopenharmony_ci#define ADF4377_0031_R031_RSV1 0x09 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/* ADF4377 REG0032 Map */ 30662306a36Sopenharmony_ci#define ADF4377_0032_ADC_CLK_SEL_MSK BIT(6) 30762306a36Sopenharmony_ci#define ADF4377_0032_R032_RSV1_MSK GENMASK(5, 0) 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci/* ADF4377 REG0032 Bit Definition */ 31062306a36Sopenharmony_ci#define ADF4377_0032_ADC_CLK_SEL_N_OP 0x0 31162306a36Sopenharmony_ci#define ADF4377_0032_ADC_CLK_SEL_SPI_CLK 0x1 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci#define ADF4377_0032_R032_RSV1 0x9 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci/* ADF4377 REG0033 Bit Definition */ 31662306a36Sopenharmony_ci#define ADF4377_0033_R033_RSV1 0x18 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci/* ADF4377 REG0034 Bit Definition */ 31962306a36Sopenharmony_ci#define ADF4377_0034_R034_RSV1 0x08 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci/* ADF4377 REG003A Bit Definition */ 32262306a36Sopenharmony_ci#define ADF4377_003A_R03A_RSV1 0x5D 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci/* ADF4377 REG003B Bit Definition */ 32562306a36Sopenharmony_ci#define ADF4377_003B_R03B_RSV1 0x2B 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci/* ADF4377 REG003D Map */ 32862306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BAND_MSK BIT(3) 32962306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_CORE_MSK BIT(2) 33062306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BIAS_MSK BIT(1) 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci/* ADF4377 REG003D Bit Definition */ 33362306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BAND_VCO_CALIB 0x0 33462306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BAND_M_VCO 0x1 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_CORE_VCO_CALIB 0x0 33762306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_CORE_M_VCO 0x1 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BIAS_VCO_CALIB 0x0 34062306a36Sopenharmony_ci#define ADF4377_003D_O_VCO_BIAS_M_VCO 0x1 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci/* ADF4377 REG0042 Map */ 34362306a36Sopenharmony_ci#define ADF4377_0042_R042_RSV1 0x05 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci/* ADF4377 REG0045 Map */ 34662306a36Sopenharmony_ci#define ADF4377_0045_ADC_ST_CNV_MSK BIT(0) 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/* ADF4377 REG0049 Map */ 34962306a36Sopenharmony_ci#define ADF4377_0049_EN_CLK2_MSK BIT(7) 35062306a36Sopenharmony_ci#define ADF4377_0049_EN_CLK1_MSK BIT(6) 35162306a36Sopenharmony_ci#define ADF4377_0049_REF_OK_MSK BIT(3) 35262306a36Sopenharmony_ci#define ADF4377_0049_ADC_BUSY_MSK BIT(2) 35362306a36Sopenharmony_ci#define ADF4377_0049_FSM_BUSY_MSK BIT(1) 35462306a36Sopenharmony_ci#define ADF4377_0049_LOCKED_MSK BIT(0) 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_ci/* ADF4377 REG004B Map */ 35762306a36Sopenharmony_ci#define ADF4377_004B_VCO_CORE_MSK GENMASK(1, 0) 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci/* ADF4377 REG004C Map */ 36062306a36Sopenharmony_ci#define ADF4377_004C_CHIP_TEMP_LSB_MSK GENMASK(7, 0) 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci/* ADF4377 REG004D Map */ 36362306a36Sopenharmony_ci#define ADF4377_004D_CHIP_TEMP_MSB_MSK BIT(0) 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci/* ADF4377 REG004F Map */ 36662306a36Sopenharmony_ci#define ADF4377_004F_VCO_BAND_MSK GENMASK(7, 0) 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci/* ADF4377 REG0051 Map */ 36962306a36Sopenharmony_ci#define ADF4377_0051_VCO_BIAS_MSK GENMASK(3, 0) 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci/* ADF4377 REG0054 Map */ 37262306a36Sopenharmony_ci#define ADF4377_0054_CHIP_VERSION_MSK GENMASK(7, 0) 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci/* Specifications */ 37562306a36Sopenharmony_ci#define ADF4377_SPI_READ_CMD BIT(7) 37662306a36Sopenharmony_ci#define ADF4377_MAX_VCO_FREQ (12800ULL * HZ_PER_MHZ) 37762306a36Sopenharmony_ci#define ADF4377_MIN_VCO_FREQ (6400ULL * HZ_PER_MHZ) 37862306a36Sopenharmony_ci#define ADF4377_MAX_REFIN_FREQ (1000 * HZ_PER_MHZ) 37962306a36Sopenharmony_ci#define ADF4377_MIN_REFIN_FREQ (10 * HZ_PER_MHZ) 38062306a36Sopenharmony_ci#define ADF4377_MAX_FREQ_PFD (500 * HZ_PER_MHZ) 38162306a36Sopenharmony_ci#define ADF4377_MIN_FREQ_PFD (3 * HZ_PER_MHZ) 38262306a36Sopenharmony_ci#define ADF4377_MAX_CLKPN_FREQ ADF4377_MAX_VCO_FREQ 38362306a36Sopenharmony_ci#define ADF4377_MIN_CLKPN_FREQ (ADF4377_MIN_VCO_FREQ / 8) 38462306a36Sopenharmony_ci#define ADF4377_FREQ_PFD_80MHZ (80 * HZ_PER_MHZ) 38562306a36Sopenharmony_ci#define ADF4377_FREQ_PFD_125MHZ (125 * HZ_PER_MHZ) 38662306a36Sopenharmony_ci#define ADF4377_FREQ_PFD_160MHZ (160 * HZ_PER_MHZ) 38762306a36Sopenharmony_ci#define ADF4377_FREQ_PFD_250MHZ (250 * HZ_PER_MHZ) 38862306a36Sopenharmony_ci#define ADF4377_FREQ_PFD_320MHZ (320 * HZ_PER_MHZ) 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cienum { 39162306a36Sopenharmony_ci ADF4377_FREQ, 39262306a36Sopenharmony_ci}; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_cienum muxout_select_mode { 39562306a36Sopenharmony_ci ADF4377_MUXOUT_HIGH_Z = 0x0, 39662306a36Sopenharmony_ci ADF4377_MUXOUT_LKDET = 0x1, 39762306a36Sopenharmony_ci ADF4377_MUXOUT_LOW = 0x2, 39862306a36Sopenharmony_ci ADF4377_MUXOUT_DIV_RCLK_2 = 0x4, 39962306a36Sopenharmony_ci ADF4377_MUXOUT_DIV_NCLK_2 = 0x5, 40062306a36Sopenharmony_ci ADF4377_MUXOUT_HIGH = 0x8, 40162306a36Sopenharmony_ci}; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cistruct adf4377_state { 40462306a36Sopenharmony_ci struct spi_device *spi; 40562306a36Sopenharmony_ci struct regmap *regmap; 40662306a36Sopenharmony_ci struct clk *clkin; 40762306a36Sopenharmony_ci /* Protect against concurrent accesses to the device and data content */ 40862306a36Sopenharmony_ci struct mutex lock; 40962306a36Sopenharmony_ci struct notifier_block nb; 41062306a36Sopenharmony_ci /* Reference Divider */ 41162306a36Sopenharmony_ci unsigned int ref_div_factor; 41262306a36Sopenharmony_ci /* PFD Frequency */ 41362306a36Sopenharmony_ci unsigned int f_pfd; 41462306a36Sopenharmony_ci /* Input Reference Clock */ 41562306a36Sopenharmony_ci unsigned int clkin_freq; 41662306a36Sopenharmony_ci /* CLKOUT Divider */ 41762306a36Sopenharmony_ci u8 clkout_div_sel; 41862306a36Sopenharmony_ci /* Feedback Divider (N) */ 41962306a36Sopenharmony_ci u16 n_int; 42062306a36Sopenharmony_ci u16 synth_lock_timeout; 42162306a36Sopenharmony_ci u16 vco_alc_timeout; 42262306a36Sopenharmony_ci u16 adc_clk_div; 42362306a36Sopenharmony_ci u16 vco_band_div; 42462306a36Sopenharmony_ci u8 dclk_div1; 42562306a36Sopenharmony_ci u8 dclk_div2; 42662306a36Sopenharmony_ci u8 dclk_mode; 42762306a36Sopenharmony_ci unsigned int f_div_rclk; 42862306a36Sopenharmony_ci enum muxout_select_mode muxout_select; 42962306a36Sopenharmony_ci struct gpio_desc *gpio_ce; 43062306a36Sopenharmony_ci struct gpio_desc *gpio_enclk1; 43162306a36Sopenharmony_ci struct gpio_desc *gpio_enclk2; 43262306a36Sopenharmony_ci u8 buf[2] __aligned(IIO_DMA_MINALIGN); 43362306a36Sopenharmony_ci}; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cistatic const char * const adf4377_muxout_modes[] = { 43662306a36Sopenharmony_ci [ADF4377_MUXOUT_HIGH_Z] = "high_z", 43762306a36Sopenharmony_ci [ADF4377_MUXOUT_LKDET] = "lock_detect", 43862306a36Sopenharmony_ci [ADF4377_MUXOUT_LOW] = "muxout_low", 43962306a36Sopenharmony_ci [ADF4377_MUXOUT_DIV_RCLK_2] = "f_div_rclk_2", 44062306a36Sopenharmony_ci [ADF4377_MUXOUT_DIV_NCLK_2] = "f_div_nclk_2", 44162306a36Sopenharmony_ci [ADF4377_MUXOUT_HIGH] = "muxout_high", 44262306a36Sopenharmony_ci}; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic const struct reg_sequence adf4377_reg_defaults[] = { 44562306a36Sopenharmony_ci { 0x42, ADF4377_0042_R042_RSV1 }, 44662306a36Sopenharmony_ci { 0x3B, ADF4377_003B_R03B_RSV1 }, 44762306a36Sopenharmony_ci { 0x3A, ADF4377_003A_R03A_RSV1 }, 44862306a36Sopenharmony_ci { 0x34, ADF4377_0034_R034_RSV1 }, 44962306a36Sopenharmony_ci { 0x33, ADF4377_0033_R033_RSV1 }, 45062306a36Sopenharmony_ci { 0x32, ADF4377_0032_R032_RSV1 }, 45162306a36Sopenharmony_ci { 0x31, ADF4377_0031_R031_RSV1 }, 45262306a36Sopenharmony_ci { 0x2C, ADF4377_002C_R02C_RSV1 }, 45362306a36Sopenharmony_ci { 0x25, ADF4377_0025_R025_RSV1 }, 45462306a36Sopenharmony_ci { 0x23, ADF4377_0023_R023_RSV1 }, 45562306a36Sopenharmony_ci { 0x22, ADF4377_0022_R022_RSV1 }, 45662306a36Sopenharmony_ci { 0x21, ADF4377_0021_R021_RSV1 }, 45762306a36Sopenharmony_ci { 0x1f, ADF4377_001F_R01F_RSV1 }, 45862306a36Sopenharmony_ci { 0x1c, ADF4377_001C_R01C_RSV1 }, 45962306a36Sopenharmony_ci}; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic const struct regmap_config adf4377_regmap_config = { 46262306a36Sopenharmony_ci .reg_bits = 16, 46362306a36Sopenharmony_ci .val_bits = 8, 46462306a36Sopenharmony_ci .read_flag_mask = BIT(7), 46562306a36Sopenharmony_ci .max_register = 0x54, 46662306a36Sopenharmony_ci}; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_cistatic int adf4377_reg_access(struct iio_dev *indio_dev, 46962306a36Sopenharmony_ci unsigned int reg, 47062306a36Sopenharmony_ci unsigned int write_val, 47162306a36Sopenharmony_ci unsigned int *read_val) 47262306a36Sopenharmony_ci{ 47362306a36Sopenharmony_ci struct adf4377_state *st = iio_priv(indio_dev); 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci if (read_val) 47662306a36Sopenharmony_ci return regmap_read(st->regmap, reg, read_val); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci return regmap_write(st->regmap, reg, write_val); 47962306a36Sopenharmony_ci} 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic const struct iio_info adf4377_info = { 48262306a36Sopenharmony_ci .debugfs_reg_access = &adf4377_reg_access, 48362306a36Sopenharmony_ci}; 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_cistatic int adf4377_soft_reset(struct adf4377_state *st) 48662306a36Sopenharmony_ci{ 48762306a36Sopenharmony_ci unsigned int read_val; 48862306a36Sopenharmony_ci int ret; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x0, ADF4377_0000_SOFT_RESET_MSK | 49162306a36Sopenharmony_ci ADF4377_0000_SOFT_RESET_R_MSK, 49262306a36Sopenharmony_ci FIELD_PREP(ADF4377_0000_SOFT_RESET_MSK, 1) | 49362306a36Sopenharmony_ci FIELD_PREP(ADF4377_0000_SOFT_RESET_R_MSK, 1)); 49462306a36Sopenharmony_ci if (ret) 49562306a36Sopenharmony_ci return ret; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci return regmap_read_poll_timeout(st->regmap, 0x0, read_val, 49862306a36Sopenharmony_ci !(read_val & (ADF4377_0000_SOFT_RESET_R_MSK | 49962306a36Sopenharmony_ci ADF4377_0000_SOFT_RESET_R_MSK)), 200, 200 * 100); 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_cistatic int adf4377_get_freq(struct adf4377_state *st, u64 *freq) 50362306a36Sopenharmony_ci{ 50462306a36Sopenharmony_ci unsigned int ref_div_factor, n_int; 50562306a36Sopenharmony_ci u64 clkin_freq; 50662306a36Sopenharmony_ci int ret; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci mutex_lock(&st->lock); 50962306a36Sopenharmony_ci ret = regmap_read(st->regmap, 0x12, &ref_div_factor); 51062306a36Sopenharmony_ci if (ret) 51162306a36Sopenharmony_ci goto exit; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci ret = regmap_bulk_read(st->regmap, 0x10, st->buf, sizeof(st->buf)); 51462306a36Sopenharmony_ci if (ret) 51562306a36Sopenharmony_ci goto exit; 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci clkin_freq = clk_get_rate(st->clkin); 51862306a36Sopenharmony_ci ref_div_factor = FIELD_GET(ADF4377_0012_R_DIV_MSK, ref_div_factor); 51962306a36Sopenharmony_ci n_int = FIELD_GET(ADF4377_0010_N_INT_LSB_MSK | ADF4377_0011_N_INT_MSB_MSK, 52062306a36Sopenharmony_ci get_unaligned_le16(&st->buf)); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci *freq = div_u64(clkin_freq, ref_div_factor) * n_int; 52362306a36Sopenharmony_ciexit: 52462306a36Sopenharmony_ci mutex_unlock(&st->lock); 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci return ret; 52762306a36Sopenharmony_ci} 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic int adf4377_set_freq(struct adf4377_state *st, u64 freq) 53062306a36Sopenharmony_ci{ 53162306a36Sopenharmony_ci unsigned int read_val; 53262306a36Sopenharmony_ci u64 f_vco; 53362306a36Sopenharmony_ci int ret; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci mutex_lock(&st->lock); 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci if (freq > ADF4377_MAX_CLKPN_FREQ || freq < ADF4377_MIN_CLKPN_FREQ) { 53862306a36Sopenharmony_ci ret = -EINVAL; 53962306a36Sopenharmony_ci goto exit; 54062306a36Sopenharmony_ci } 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | 54362306a36Sopenharmony_ci ADF4377_001C_EN_DRCLK_MSK, 54462306a36Sopenharmony_ci FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 1) | 54562306a36Sopenharmony_ci FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 1)); 54662306a36Sopenharmony_ci if (ret) 54762306a36Sopenharmony_ci goto exit; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_AUTOCAL_MSK | 55062306a36Sopenharmony_ci ADF4377_0011_DCLK_DIV2_MSK, 55162306a36Sopenharmony_ci FIELD_PREP(ADF4377_0011_EN_AUTOCAL_MSK, 1) | 55262306a36Sopenharmony_ci FIELD_PREP(ADF4377_0011_DCLK_DIV2_MSK, st->dclk_div2)); 55362306a36Sopenharmony_ci if (ret) 55462306a36Sopenharmony_ci goto exit; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x2E, ADF4377_002E_EN_ADC_CNV_MSK | 55762306a36Sopenharmony_ci ADF4377_002E_EN_ADC_MSK | 55862306a36Sopenharmony_ci ADF4377_002E_ADC_A_CONV_MSK, 55962306a36Sopenharmony_ci FIELD_PREP(ADF4377_002E_EN_ADC_CNV_MSK, 1) | 56062306a36Sopenharmony_ci FIELD_PREP(ADF4377_002E_EN_ADC_MSK, 1) | 56162306a36Sopenharmony_ci FIELD_PREP(ADF4377_002E_ADC_A_CONV_MSK, 56262306a36Sopenharmony_ci ADF4377_002E_ADC_A_CONV_VCO_CALIB)); 56362306a36Sopenharmony_ci if (ret) 56462306a36Sopenharmony_ci goto exit; 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, 56762306a36Sopenharmony_ci FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 1)); 56862306a36Sopenharmony_ci if (ret) 56962306a36Sopenharmony_ci goto exit; 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x2F, ADF4377_002F_DCLK_DIV1_MSK, 57262306a36Sopenharmony_ci FIELD_PREP(ADF4377_002F_DCLK_DIV1_MSK, st->dclk_div1)); 57362306a36Sopenharmony_ci if (ret) 57462306a36Sopenharmony_ci goto exit; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x24, ADF4377_0024_DCLK_MODE_MSK, 57762306a36Sopenharmony_ci FIELD_PREP(ADF4377_0024_DCLK_MODE_MSK, st->dclk_mode)); 57862306a36Sopenharmony_ci if (ret) 57962306a36Sopenharmony_ci goto exit; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x27, 58262306a36Sopenharmony_ci FIELD_PREP(ADF4377_0027_SYNTH_LOCK_TO_LSB_MSK, 58362306a36Sopenharmony_ci st->synth_lock_timeout)); 58462306a36Sopenharmony_ci if (ret) 58562306a36Sopenharmony_ci goto exit; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x28, ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, 58862306a36Sopenharmony_ci FIELD_PREP(ADF4377_0028_SYNTH_LOCK_TO_MSB_MSK, 58962306a36Sopenharmony_ci st->synth_lock_timeout >> 8)); 59062306a36Sopenharmony_ci if (ret) 59162306a36Sopenharmony_ci goto exit; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x29, 59462306a36Sopenharmony_ci FIELD_PREP(ADF4377_0029_VCO_ALC_TO_LSB_MSK, 59562306a36Sopenharmony_ci st->vco_alc_timeout)); 59662306a36Sopenharmony_ci if (ret) 59762306a36Sopenharmony_ci goto exit; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x2A, ADF4377_002A_VCO_ALC_TO_MSB_MSK, 60062306a36Sopenharmony_ci FIELD_PREP(ADF4377_002A_VCO_ALC_TO_MSB_MSK, 60162306a36Sopenharmony_ci st->vco_alc_timeout >> 8)); 60262306a36Sopenharmony_ci if (ret) 60362306a36Sopenharmony_ci goto exit; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x26, 60662306a36Sopenharmony_ci FIELD_PREP(ADF4377_0026_VCO_BAND_DIV_MSK, st->vco_band_div)); 60762306a36Sopenharmony_ci if (ret) 60862306a36Sopenharmony_ci goto exit; 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x2D, 61162306a36Sopenharmony_ci FIELD_PREP(ADF4377_002D_ADC_CLK_DIV_MSK, st->adc_clk_div)); 61262306a36Sopenharmony_ci if (ret) 61362306a36Sopenharmony_ci goto exit; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci st->clkout_div_sel = 0; 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci f_vco = freq; 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci while (f_vco < ADF4377_MIN_VCO_FREQ) { 62062306a36Sopenharmony_ci f_vco <<= 1; 62162306a36Sopenharmony_ci st->clkout_div_sel++; 62262306a36Sopenharmony_ci } 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci st->n_int = div_u64(freq, st->f_pfd); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x11, ADF4377_0011_EN_RDBLR_MSK | 62762306a36Sopenharmony_ci ADF4377_0011_N_INT_MSB_MSK, 62862306a36Sopenharmony_ci FIELD_PREP(ADF4377_0011_EN_RDBLR_MSK, 0) | 62962306a36Sopenharmony_ci FIELD_PREP(ADF4377_0011_N_INT_MSB_MSK, st->n_int >> 8)); 63062306a36Sopenharmony_ci if (ret) 63162306a36Sopenharmony_ci goto exit; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x12, ADF4377_0012_R_DIV_MSK | 63462306a36Sopenharmony_ci ADF4377_0012_CLKOUT_DIV_MSK, 63562306a36Sopenharmony_ci FIELD_PREP(ADF4377_0012_CLKOUT_DIV_MSK, st->clkout_div_sel) | 63662306a36Sopenharmony_ci FIELD_PREP(ADF4377_0012_R_DIV_MSK, st->ref_div_factor)); 63762306a36Sopenharmony_ci if (ret) 63862306a36Sopenharmony_ci goto exit; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x10, 64162306a36Sopenharmony_ci FIELD_PREP(ADF4377_0010_N_INT_LSB_MSK, st->n_int)); 64262306a36Sopenharmony_ci if (ret) 64362306a36Sopenharmony_ci goto exit; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci ret = regmap_read_poll_timeout(st->regmap, 0x49, read_val, 64662306a36Sopenharmony_ci !(read_val & (ADF4377_0049_FSM_BUSY_MSK)), 200, 200 * 100); 64762306a36Sopenharmony_ci if (ret) 64862306a36Sopenharmony_ci goto exit; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci /* Disable EN_DNCLK, EN_DRCLK */ 65162306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x1C, ADF4377_001C_EN_DNCLK_MSK | 65262306a36Sopenharmony_ci ADF4377_001C_EN_DRCLK_MSK, 65362306a36Sopenharmony_ci FIELD_PREP(ADF4377_001C_EN_DNCLK_MSK, 0) | 65462306a36Sopenharmony_ci FIELD_PREP(ADF4377_001C_EN_DRCLK_MSK, 0)); 65562306a36Sopenharmony_ci if (ret) 65662306a36Sopenharmony_ci goto exit; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci /* Disable EN_ADC_CLK */ 65962306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x20, ADF4377_0020_EN_ADC_CLK_MSK, 66062306a36Sopenharmony_ci FIELD_PREP(ADF4377_0020_EN_ADC_CLK_MSK, 0)); 66162306a36Sopenharmony_ci if (ret) 66262306a36Sopenharmony_ci goto exit; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* Set output Amplitude */ 66562306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x19, ADF4377_0019_CLKOUT2_OP_MSK | 66662306a36Sopenharmony_ci ADF4377_0019_CLKOUT1_OP_MSK, 66762306a36Sopenharmony_ci FIELD_PREP(ADF4377_0019_CLKOUT1_OP_MSK, 66862306a36Sopenharmony_ci ADF4377_0019_CLKOUT_420MV) | 66962306a36Sopenharmony_ci FIELD_PREP(ADF4377_0019_CLKOUT2_OP_MSK, 67062306a36Sopenharmony_ci ADF4377_0019_CLKOUT_420MV)); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ciexit: 67362306a36Sopenharmony_ci mutex_unlock(&st->lock); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci return ret; 67662306a36Sopenharmony_ci} 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_cistatic void adf4377_gpio_init(struct adf4377_state *st) 67962306a36Sopenharmony_ci{ 68062306a36Sopenharmony_ci if (st->gpio_ce) { 68162306a36Sopenharmony_ci gpiod_set_value(st->gpio_ce, 1); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci /* Delay for SPI register bits to settle to their power-on reset state */ 68462306a36Sopenharmony_ci fsleep(200); 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci if (st->gpio_enclk1) 68862306a36Sopenharmony_ci gpiod_set_value(st->gpio_enclk1, 1); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci if (st->gpio_enclk2) 69162306a36Sopenharmony_ci gpiod_set_value(st->gpio_enclk2, 1); 69262306a36Sopenharmony_ci} 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_cistatic int adf4377_init(struct adf4377_state *st) 69562306a36Sopenharmony_ci{ 69662306a36Sopenharmony_ci struct spi_device *spi = st->spi; 69762306a36Sopenharmony_ci int ret; 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci adf4377_gpio_init(st); 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci ret = adf4377_soft_reset(st); 70262306a36Sopenharmony_ci if (ret) { 70362306a36Sopenharmony_ci dev_err(&spi->dev, "Failed to soft reset.\n"); 70462306a36Sopenharmony_ci return ret; 70562306a36Sopenharmony_ci } 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci ret = regmap_multi_reg_write(st->regmap, adf4377_reg_defaults, 70862306a36Sopenharmony_ci ARRAY_SIZE(adf4377_reg_defaults)); 70962306a36Sopenharmony_ci if (ret) { 71062306a36Sopenharmony_ci dev_err(&spi->dev, "Failed to set default registers.\n"); 71162306a36Sopenharmony_ci return ret; 71262306a36Sopenharmony_ci } 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x00, 71562306a36Sopenharmony_ci ADF4377_0000_SDO_ACTIVE_MSK | ADF4377_0000_SDO_ACTIVE_R_MSK, 71662306a36Sopenharmony_ci FIELD_PREP(ADF4377_0000_SDO_ACTIVE_MSK, 71762306a36Sopenharmony_ci ADF4377_0000_SDO_ACTIVE_SPI_4W) | 71862306a36Sopenharmony_ci FIELD_PREP(ADF4377_0000_SDO_ACTIVE_R_MSK, 71962306a36Sopenharmony_ci ADF4377_0000_SDO_ACTIVE_SPI_4W)); 72062306a36Sopenharmony_ci if (ret) { 72162306a36Sopenharmony_ci dev_err(&spi->dev, "Failed to set 4-Wire Operation.\n"); 72262306a36Sopenharmony_ci return ret; 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci 72562306a36Sopenharmony_ci st->clkin_freq = clk_get_rate(st->clkin); 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci /* Power Up */ 72862306a36Sopenharmony_ci ret = regmap_write(st->regmap, 0x1a, 72962306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_ALL_MSK, 0) | 73062306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_RDIV_MSK, 0) | 73162306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_NDIV_MSK, 0) | 73262306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_VCO_MSK, 0) | 73362306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_LD_MSK, 0) | 73462306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_PFDCP_MSK, 0) | 73562306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 0) | 73662306a36Sopenharmony_ci FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 0)); 73762306a36Sopenharmony_ci if (ret) { 73862306a36Sopenharmony_ci dev_err(&spi->dev, "Failed to set power down registers.\n"); 73962306a36Sopenharmony_ci return ret; 74062306a36Sopenharmony_ci } 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci /* Set Mux Output */ 74362306a36Sopenharmony_ci ret = regmap_update_bits(st->regmap, 0x1D, 74462306a36Sopenharmony_ci ADF4377_001D_MUXOUT_MSK, 74562306a36Sopenharmony_ci FIELD_PREP(ADF4377_001D_MUXOUT_MSK, st->muxout_select)); 74662306a36Sopenharmony_ci if (ret) 74762306a36Sopenharmony_ci return ret; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci /* Compute PFD */ 75062306a36Sopenharmony_ci st->ref_div_factor = 0; 75162306a36Sopenharmony_ci do { 75262306a36Sopenharmony_ci st->ref_div_factor++; 75362306a36Sopenharmony_ci st->f_pfd = st->clkin_freq / st->ref_div_factor; 75462306a36Sopenharmony_ci } while (st->f_pfd > ADF4377_MAX_FREQ_PFD); 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci if (st->f_pfd > ADF4377_MAX_FREQ_PFD || st->f_pfd < ADF4377_MIN_FREQ_PFD) 75762306a36Sopenharmony_ci return -EINVAL; 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci st->f_div_rclk = st->f_pfd; 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_ci if (st->f_pfd <= ADF4377_FREQ_PFD_80MHZ) { 76262306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; 76362306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; 76462306a36Sopenharmony_ci st->dclk_mode = 0; 76562306a36Sopenharmony_ci } else if (st->f_pfd <= ADF4377_FREQ_PFD_125MHZ) { 76662306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_1; 76762306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; 76862306a36Sopenharmony_ci st->dclk_mode = 1; 76962306a36Sopenharmony_ci } else if (st->f_pfd <= ADF4377_FREQ_PFD_160MHZ) { 77062306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; 77162306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; 77262306a36Sopenharmony_ci st->dclk_mode = 0; 77362306a36Sopenharmony_ci st->f_div_rclk /= 2; 77462306a36Sopenharmony_ci } else if (st->f_pfd <= ADF4377_FREQ_PFD_250MHZ) { 77562306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; 77662306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_1; 77762306a36Sopenharmony_ci st->dclk_mode = 1; 77862306a36Sopenharmony_ci st->f_div_rclk /= 2; 77962306a36Sopenharmony_ci } else if (st->f_pfd <= ADF4377_FREQ_PFD_320MHZ) { 78062306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; 78162306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; 78262306a36Sopenharmony_ci st->dclk_mode = 0; 78362306a36Sopenharmony_ci st->f_div_rclk /= 4; 78462306a36Sopenharmony_ci } else { 78562306a36Sopenharmony_ci st->dclk_div1 = ADF4377_002F_DCLK_DIV1_2; 78662306a36Sopenharmony_ci st->dclk_div2 = ADF4377_0011_DCLK_DIV2_2; 78762306a36Sopenharmony_ci st->dclk_mode = 1; 78862306a36Sopenharmony_ci st->f_div_rclk /= 4; 78962306a36Sopenharmony_ci } 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci st->synth_lock_timeout = DIV_ROUND_UP(st->f_div_rclk, 50000); 79262306a36Sopenharmony_ci st->vco_alc_timeout = DIV_ROUND_UP(st->f_div_rclk, 20000); 79362306a36Sopenharmony_ci st->vco_band_div = DIV_ROUND_UP(st->f_div_rclk, 150000 * 16 * (1 << st->dclk_mode)); 79462306a36Sopenharmony_ci st->adc_clk_div = DIV_ROUND_UP((st->f_div_rclk / 400000 - 2), 4); 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci return 0; 79762306a36Sopenharmony_ci} 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_cistatic ssize_t adf4377_read(struct iio_dev *indio_dev, uintptr_t private, 80062306a36Sopenharmony_ci const struct iio_chan_spec *chan, char *buf) 80162306a36Sopenharmony_ci{ 80262306a36Sopenharmony_ci struct adf4377_state *st = iio_priv(indio_dev); 80362306a36Sopenharmony_ci u64 val = 0; 80462306a36Sopenharmony_ci int ret; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci switch ((u32)private) { 80762306a36Sopenharmony_ci case ADF4377_FREQ: 80862306a36Sopenharmony_ci ret = adf4377_get_freq(st, &val); 80962306a36Sopenharmony_ci if (ret) 81062306a36Sopenharmony_ci return ret; 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci return sysfs_emit(buf, "%llu\n", val); 81362306a36Sopenharmony_ci default: 81462306a36Sopenharmony_ci return -EINVAL; 81562306a36Sopenharmony_ci } 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_cistatic ssize_t adf4377_write(struct iio_dev *indio_dev, uintptr_t private, 81962306a36Sopenharmony_ci const struct iio_chan_spec *chan, const char *buf, 82062306a36Sopenharmony_ci size_t len) 82162306a36Sopenharmony_ci{ 82262306a36Sopenharmony_ci struct adf4377_state *st = iio_priv(indio_dev); 82362306a36Sopenharmony_ci unsigned long long freq; 82462306a36Sopenharmony_ci int ret; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci switch ((u32)private) { 82762306a36Sopenharmony_ci case ADF4377_FREQ: 82862306a36Sopenharmony_ci ret = kstrtoull(buf, 10, &freq); 82962306a36Sopenharmony_ci if (ret) 83062306a36Sopenharmony_ci return ret; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci ret = adf4377_set_freq(st, freq); 83362306a36Sopenharmony_ci if (ret) 83462306a36Sopenharmony_ci return ret; 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci return len; 83762306a36Sopenharmony_ci default: 83862306a36Sopenharmony_ci return -EINVAL; 83962306a36Sopenharmony_ci } 84062306a36Sopenharmony_ci} 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci#define _ADF4377_EXT_INFO(_name, _shared, _ident) { \ 84362306a36Sopenharmony_ci .name = _name, \ 84462306a36Sopenharmony_ci .read = adf4377_read, \ 84562306a36Sopenharmony_ci .write = adf4377_write, \ 84662306a36Sopenharmony_ci .private = _ident, \ 84762306a36Sopenharmony_ci .shared = _shared, \ 84862306a36Sopenharmony_ci } 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_cistatic const struct iio_chan_spec_ext_info adf4377_ext_info[] = { 85162306a36Sopenharmony_ci /* 85262306a36Sopenharmony_ci * Usually we use IIO_CHAN_INFO_FREQUENCY, but there are 85362306a36Sopenharmony_ci * values > 2^32 in order to support the entire frequency range 85462306a36Sopenharmony_ci * in Hz. 85562306a36Sopenharmony_ci */ 85662306a36Sopenharmony_ci _ADF4377_EXT_INFO("frequency", IIO_SEPARATE, ADF4377_FREQ), 85762306a36Sopenharmony_ci { } 85862306a36Sopenharmony_ci}; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_cistatic const struct iio_chan_spec adf4377_channels[] = { 86162306a36Sopenharmony_ci { 86262306a36Sopenharmony_ci .type = IIO_ALTVOLTAGE, 86362306a36Sopenharmony_ci .indexed = 1, 86462306a36Sopenharmony_ci .output = 1, 86562306a36Sopenharmony_ci .channel = 0, 86662306a36Sopenharmony_ci .ext_info = adf4377_ext_info, 86762306a36Sopenharmony_ci }, 86862306a36Sopenharmony_ci}; 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_cistatic int adf4377_properties_parse(struct adf4377_state *st) 87162306a36Sopenharmony_ci{ 87262306a36Sopenharmony_ci struct spi_device *spi = st->spi; 87362306a36Sopenharmony_ci const char *str; 87462306a36Sopenharmony_ci int ret; 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci st->clkin = devm_clk_get_enabled(&spi->dev, "ref_in"); 87762306a36Sopenharmony_ci if (IS_ERR(st->clkin)) 87862306a36Sopenharmony_ci return dev_err_probe(&spi->dev, PTR_ERR(st->clkin), 87962306a36Sopenharmony_ci "failed to get the reference input clock\n"); 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci st->gpio_ce = devm_gpiod_get_optional(&st->spi->dev, "chip-enable", 88262306a36Sopenharmony_ci GPIOD_OUT_LOW); 88362306a36Sopenharmony_ci if (IS_ERR(st->gpio_ce)) 88462306a36Sopenharmony_ci return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_ce), 88562306a36Sopenharmony_ci "failed to get the CE GPIO\n"); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci st->gpio_enclk1 = devm_gpiod_get_optional(&st->spi->dev, "clk1-enable", 88862306a36Sopenharmony_ci GPIOD_OUT_LOW); 88962306a36Sopenharmony_ci if (IS_ERR(st->gpio_enclk1)) 89062306a36Sopenharmony_ci return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk1), 89162306a36Sopenharmony_ci "failed to get the CE GPIO\n"); 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci st->gpio_enclk2 = devm_gpiod_get_optional(&st->spi->dev, "clk2-enable", 89462306a36Sopenharmony_ci GPIOD_OUT_LOW); 89562306a36Sopenharmony_ci if (IS_ERR(st->gpio_enclk2)) 89662306a36Sopenharmony_ci return dev_err_probe(&spi->dev, PTR_ERR(st->gpio_enclk2), 89762306a36Sopenharmony_ci "failed to get the CE GPIO\n"); 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci ret = device_property_read_string(&spi->dev, "adi,muxout-select", &str); 90062306a36Sopenharmony_ci if (ret) { 90162306a36Sopenharmony_ci st->muxout_select = ADF4377_MUXOUT_HIGH_Z; 90262306a36Sopenharmony_ci } else { 90362306a36Sopenharmony_ci ret = match_string(adf4377_muxout_modes, ARRAY_SIZE(adf4377_muxout_modes), str); 90462306a36Sopenharmony_ci if (ret < 0) 90562306a36Sopenharmony_ci return ret; 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci st->muxout_select = ret; 90862306a36Sopenharmony_ci } 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci return 0; 91162306a36Sopenharmony_ci} 91262306a36Sopenharmony_ci 91362306a36Sopenharmony_cistatic int adf4377_freq_change(struct notifier_block *nb, unsigned long action, void *data) 91462306a36Sopenharmony_ci{ 91562306a36Sopenharmony_ci struct adf4377_state *st = container_of(nb, struct adf4377_state, nb); 91662306a36Sopenharmony_ci int ret; 91762306a36Sopenharmony_ci 91862306a36Sopenharmony_ci if (action == POST_RATE_CHANGE) { 91962306a36Sopenharmony_ci mutex_lock(&st->lock); 92062306a36Sopenharmony_ci ret = notifier_from_errno(adf4377_init(st)); 92162306a36Sopenharmony_ci mutex_unlock(&st->lock); 92262306a36Sopenharmony_ci return ret; 92362306a36Sopenharmony_ci } 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci return NOTIFY_OK; 92662306a36Sopenharmony_ci} 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_cistatic int adf4377_probe(struct spi_device *spi) 92962306a36Sopenharmony_ci{ 93062306a36Sopenharmony_ci struct iio_dev *indio_dev; 93162306a36Sopenharmony_ci struct regmap *regmap; 93262306a36Sopenharmony_ci struct adf4377_state *st; 93362306a36Sopenharmony_ci int ret; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); 93662306a36Sopenharmony_ci if (!indio_dev) 93762306a36Sopenharmony_ci return -ENOMEM; 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci regmap = devm_regmap_init_spi(spi, &adf4377_regmap_config); 94062306a36Sopenharmony_ci if (IS_ERR(regmap)) 94162306a36Sopenharmony_ci return PTR_ERR(regmap); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci st = iio_priv(indio_dev); 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci indio_dev->info = &adf4377_info; 94662306a36Sopenharmony_ci indio_dev->name = "adf4377"; 94762306a36Sopenharmony_ci indio_dev->channels = adf4377_channels; 94862306a36Sopenharmony_ci indio_dev->num_channels = ARRAY_SIZE(adf4377_channels); 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci st->regmap = regmap; 95162306a36Sopenharmony_ci st->spi = spi; 95262306a36Sopenharmony_ci mutex_init(&st->lock); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci ret = adf4377_properties_parse(st); 95562306a36Sopenharmony_ci if (ret) 95662306a36Sopenharmony_ci return ret; 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci st->nb.notifier_call = adf4377_freq_change; 95962306a36Sopenharmony_ci ret = devm_clk_notifier_register(&spi->dev, st->clkin, &st->nb); 96062306a36Sopenharmony_ci if (ret) 96162306a36Sopenharmony_ci return ret; 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci ret = adf4377_init(st); 96462306a36Sopenharmony_ci if (ret) 96562306a36Sopenharmony_ci return ret; 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci return devm_iio_device_register(&spi->dev, indio_dev); 96862306a36Sopenharmony_ci} 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_cistatic const struct spi_device_id adf4377_id[] = { 97162306a36Sopenharmony_ci { "adf4377", 0 }, 97262306a36Sopenharmony_ci {} 97362306a36Sopenharmony_ci}; 97462306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, adf4377_id); 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_cistatic const struct of_device_id adf4377_of_match[] = { 97762306a36Sopenharmony_ci { .compatible = "adi,adf4377" }, 97862306a36Sopenharmony_ci {} 97962306a36Sopenharmony_ci}; 98062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, adf4377_of_match); 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_cistatic struct spi_driver adf4377_driver = { 98362306a36Sopenharmony_ci .driver = { 98462306a36Sopenharmony_ci .name = "adf4377", 98562306a36Sopenharmony_ci .of_match_table = adf4377_of_match, 98662306a36Sopenharmony_ci }, 98762306a36Sopenharmony_ci .probe = adf4377_probe, 98862306a36Sopenharmony_ci .id_table = adf4377_id, 98962306a36Sopenharmony_ci}; 99062306a36Sopenharmony_cimodule_spi_driver(adf4377_driver); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ciMODULE_AUTHOR("Antoniu Miclaus <antoniu.miclaus@analog.com>"); 99362306a36Sopenharmony_ciMODULE_DESCRIPTION("Analog Devices ADF4377"); 99462306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 995