Commit 6489b8749d33ad35b8d2e24674708508f4bedabc
1 parent
01d6714696
Exists in
master
driver prenant le mot en bits et non la frequence
Showing 2 changed files with 1123 additions and 0 deletions Inline Diff
220124_AD9832driver/ad9832.c
| File was created | 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | |||
| 3 | * AD9832 SPI DDS driver | |||
| 4 | * | |||
| 5 | * Copyright 2011 Analog Devices Inc. | |||
| 6 | */ | |||
| 7 | ||||
| 8 | #include <asm/div64.h> | |||
| 9 | ||||
| 10 | #include <linux/clk.h> | |||
| 11 | #include <linux/device.h> | |||
| 12 | #include <linux/err.h> | |||
| 13 | #include <linux/kernel.h> | |||
| 14 | #include <linux/module.h> | |||
| 15 | #include <linux/regulator/consumer.h> | |||
| 16 | #include <linux/slab.h> | |||
| 17 | #include <linux/spi/spi.h> | |||
| 18 | #include <linux/sysfs.h> | |||
| 19 | ||||
| 20 | #include <linux/iio/iio.h> | |||
| 21 | #include <linux/iio/sysfs.h> | |||
| 22 | ||||
| 23 | #include "ad9832.h" | |||
| 24 | ||||
| 25 | #include "dds.h" | |||
| 26 | ||||
| 27 | /* Registers */ | |||
| 28 | ||||
| 29 | #define AD9832_FREQ0LL 0x0 | |||
| 30 | #define AD9832_FREQ0HL 0x1 | |||
| 31 | #define AD9832_FREQ0LM 0x2 | |||
| 32 | #define AD9832_FREQ0HM 0x3 | |||
| 33 | #define AD9832_FREQ1LL 0x4 | |||
| 34 | #define AD9832_FREQ1HL 0x5 | |||
| 35 | #define AD9832_FREQ1LM 0x6 | |||
| 36 | #define AD9832_FREQ1HM 0x7 | |||
| 37 | #define AD9832_PHASE0L 0x8 | |||
| 38 | #define AD9832_PHASE0H 0x9 | |||
| 39 | #define AD9832_PHASE1L 0xA | |||
| 40 | #define AD9832_PHASE1H 0xB | |||
| 41 | #define AD9832_PHASE2L 0xC | |||
| 42 | #define AD9832_PHASE2H 0xD | |||
| 43 | #define AD9832_PHASE3L 0xE | |||
| 44 | #define AD9832_PHASE3H 0xF | |||
| 45 | ||||
| 46 | #define AD9832_PHASE_SYM 0x10 | |||
| 47 | #define AD9832_FREQ_SYM 0x11 | |||
| 48 | #define AD9832_PINCTRL_EN 0x12 | |||
| 49 | #define AD9832_OUTPUT_EN 0x13 | |||
| 50 | ||||
| 51 | /* Command Control Bits */ | |||
| 52 | ||||
| 53 | #define AD9832_CMD_PHA8BITSW 0x1 | |||
| 54 | #define AD9832_CMD_PHA16BITSW 0x0 | |||
| 55 | #define AD9832_CMD_FRE8BITSW 0x3 | |||
| 56 | #define AD9832_CMD_FRE16BITSW 0x2 | |||
| 57 | #define AD9832_CMD_FPSELECT 0x6 | |||
| 58 | #define AD9832_CMD_SYNCSELSRC 0x8 | |||
| 59 | #define AD9832_CMD_SLEEPRESCLR 0xC | |||
| 60 | ||||
| 61 | #define AD9832_FREQ BIT(11) | |||
| 62 | #define AD9832_PHASE(x) (((x) & 3) << 9) | |||
| 63 | #define AD9832_SYNC BIT(13) | |||
| 64 | #define AD9832_SELSRC BIT(12) | |||
| 65 | #define AD9832_SLEEP BIT(13) | |||
| 66 | #define AD9832_RESET BIT(12) | |||
| 67 | #define AD9832_CLR BIT(11) | |||
| 68 | #define CMD_SHIFT 12 | |||
| 69 | #define ADD_SHIFT 8 | |||
| 70 | #define AD9832_FREQ_BITS 32 | |||
| 71 | #define AD9832_PHASE_BITS 12 | |||
| 72 | #define RES_MASK(bits) ((1 << (bits)) - 1) | |||
| 73 | ||||
| 74 | /** | |||
| 75 | * struct ad9832_state - driver instance specific data | |||
| 76 | * @spi: spi_device | |||
| 77 | * @avdd: supply regulator for the analog section | |||
| 78 | * @dvdd: supply regulator for the digital section | |||
| 79 | * @mclk: external master clock | |||
| 80 | * @ctrl_fp: cached frequency/phase control word | |||
| 81 | * @ctrl_ss: cached sync/selsrc control word | |||
| 82 | * @ctrl_src: cached sleep/reset/clr word | |||
| 83 | * @xfer: default spi transfer | |||
| 84 | * @msg: default spi message | |||
| 85 | * @freq_xfer: tuning word spi transfer | |||
| 86 | * @freq_msg: tuning word spi message | |||
| 87 | * @phase_xfer: tuning word spi transfer | |||
| 88 | * @phase_msg: tuning word spi message | |||
| 89 | * @lock protect sensor state | |||
| 90 | * @data: spi transmit buffer | |||
| 91 | * @phase_data: tuning word spi transmit buffer | |||
| 92 | * @freq_data: tuning word spi transmit buffer | |||
| 93 | */ | |||
| 94 | ||||
| 95 | struct ad9832_state { | |||
| 96 | struct spi_device *spi; | |||
| 97 | struct regulator *avdd; | |||
| 98 | struct regulator *dvdd; | |||
| 99 | struct clk *mclk; | |||
| 100 | unsigned short ctrl_fp; | |||
| 101 | unsigned short ctrl_ss; | |||
| 102 | unsigned short ctrl_src; | |||
| 103 | struct spi_transfer xfer; | |||
| 104 | struct spi_message msg; | |||
| 105 | struct spi_transfer freq_xfer[4]; | |||
| 106 | struct spi_message freq_msg; | |||
| 107 | struct spi_transfer phase_xfer[2]; | |||
| 108 | struct spi_message phase_msg; | |||
| 109 | struct mutex lock; /* protect sensor state */ | |||
| 110 | /* | |||
| 111 | * DMA (thus cache coherency maintenance) requires the | |||
| 112 | * transfer buffers to live in their own cache lines. | |||
| 113 | */ | |||
| 114 | union { | |||
| 115 | __be16 freq_data[4]____cacheline_aligned; | |||
| 116 | __be16 phase_data[2]; | |||
| 117 | __be16 data; | |||
| 118 | }; | |||
| 119 | }; | |||
| 120 | ||||
| 121 | static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) | |||
| 122 | { | |||
| 123 | // unsigned long long freqreg = (u64)fout * | |||
| 124 | // (u64)((u64)1L << AD9832_FREQ_BITS); | |||
| 125 | // do_div(freqreg, mclk); | |||
| 126 | return fout; // freqreg; | |||
| 127 | } | |||
| 128 | ||||
| 129 | static int ad9832_write_frequency(struct ad9832_state *st, | |||
| 130 | unsigned int addr, unsigned long fout) | |||
| 131 | { | |||
| 132 | unsigned long regval; | |||
| 133 | ||||
| 134 | // if (fout > (clk_get_rate(st->mclk) / 2)) | |||
| 135 | // return -EINVAL; | |||
| 136 | ||||
| 137 | regval = ad9832_calc_freqreg(clk_get_rate(st->mclk), fout); | |||
| 138 | ||||
| 139 | st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | | |||
| 140 | (addr << ADD_SHIFT) | | |||
| 141 | ((regval >> 24) & 0xFF)); | |||
| 142 | st->freq_data[1] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | | |||
| 143 | ((addr - 1) << ADD_SHIFT) | | |||
| 144 | ((regval >> 16) & 0xFF)); | |||
| 145 | st->freq_data[2] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | | |||
| 146 | ((addr - 2) << ADD_SHIFT) | | |||
| 147 | ((regval >> 8) & 0xFF)); | |||
| 148 | st->freq_data[3] = cpu_to_be16((AD9832_CMD_FRE16BITSW << CMD_SHIFT) | | |||
| 149 | ((addr - 3) << ADD_SHIFT) | | |||
| 150 | ((regval >> 0) & 0xFF)); | |||
| 151 | ||||
| 152 | return spi_sync(st->spi, &st->freq_msg); | |||
| 153 | } | |||
| 154 | ||||
| 155 | static int ad9832_write_phase(struct ad9832_state *st, | |||
| 156 | unsigned long addr, unsigned long phase) | |||
| 157 | { | |||
| 158 | if (phase > BIT(AD9832_PHASE_BITS)) | |||
| 159 | return -EINVAL; | |||
| 160 | ||||
| 161 | st->phase_data[0] = cpu_to_be16((AD9832_CMD_PHA8BITSW << CMD_SHIFT) | | |||
| 162 | (addr << ADD_SHIFT) | | |||
| 163 | ((phase >> 8) & 0xFF)); | |||
| 164 | st->phase_data[1] = cpu_to_be16((AD9832_CMD_PHA16BITSW << CMD_SHIFT) | | |||
| 165 | ((addr - 1) << ADD_SHIFT) | | |||
| 166 | (phase & 0xFF)); | |||
| 167 | ||||
| 168 | return spi_sync(st->spi, &st->phase_msg); | |||
| 169 | } | |||
| 170 | ||||
| 171 | static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr, | |||
| 172 | const char *buf, size_t len) | |||
| 173 | { | |||
| 174 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | |||
| 175 | struct ad9832_state *st = iio_priv(indio_dev); | |||
| 176 | struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); | |||
| 177 | int ret; | |||
| 178 | unsigned long val; | |||
| 179 | ||||
| 180 | ret = kstrtoul(buf, 10, &val); | |||
| 181 | if (ret) | |||
| 182 | goto error_ret; | |||
| 183 | ||||
| 184 | mutex_lock(&st->lock); | |||
| 185 | switch ((u32)this_attr->address) { | |||
| 186 | case AD9832_FREQ0HM: | |||
| 187 | case AD9832_FREQ1HM: | |||
| 188 | ret = ad9832_write_frequency(st, this_attr->address, val); | |||
| 189 | break; | |||
| 190 | case AD9832_PHASE0H: | |||
| 191 | case AD9832_PHASE1H: | |||
| 192 | case AD9832_PHASE2H: | |||
| 193 | case AD9832_PHASE3H: | |||
| 194 | ret = ad9832_write_phase(st, this_attr->address, val); | |||
| 195 | break; | |||
| 196 | case AD9832_PINCTRL_EN: | |||
| 197 | if (val) | |||
| 198 | st->ctrl_ss &= ~AD9832_SELSRC; | |||
| 199 | else | |||
| 200 | st->ctrl_ss |= AD9832_SELSRC; | |||
| 201 | st->data = cpu_to_be16((AD9832_CMD_SYNCSELSRC << CMD_SHIFT) | | |||
| 202 | st->ctrl_ss); | |||
| 203 | ret = spi_sync(st->spi, &st->msg); | |||
| 204 | break; | |||
| 205 | case AD9832_FREQ_SYM: | |||
| 206 | if (val == 1) { | |||
| 207 | st->ctrl_fp |= AD9832_FREQ; | |||
| 208 | } else if (val == 0) { | |||
| 209 | st->ctrl_fp &= ~AD9832_FREQ; | |||
| 210 | } else { | |||
| 211 | ret = -EINVAL; | |||
| 212 | break; | |||
| 213 | } | |||
| 214 | st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | | |||
| 215 | st->ctrl_fp); | |||
| 216 | ret = spi_sync(st->spi, &st->msg); | |||
| 217 | break; | |||
| 218 | case AD9832_PHASE_SYM: | |||
| 219 | if (val > 3) { | |||
| 220 | ret = -EINVAL; | |||
| 221 | break; | |||
| 222 | } | |||
| 223 | ||||
| 224 | st->ctrl_fp &= ~AD9832_PHASE(3); | |||
| 225 | st->ctrl_fp |= AD9832_PHASE(val); | |||
| 226 | ||||
| 227 | st->data = cpu_to_be16((AD9832_CMD_FPSELECT << CMD_SHIFT) | | |||
| 228 | st->ctrl_fp); | |||
| 229 | ret = spi_sync(st->spi, &st->msg); | |||
| 230 | break; | |||
| 231 | case AD9832_OUTPUT_EN: | |||
| 232 | if (val) | |||
| 233 | st->ctrl_src &= ~(AD9832_RESET | AD9832_SLEEP | | |||
| 234 | AD9832_CLR); | |||
| 235 | else | |||
| 236 | st->ctrl_src |= AD9832_RESET; | |||
| 237 | ||||
| 238 | st->data = cpu_to_be16((AD9832_CMD_SLEEPRESCLR << CMD_SHIFT) | | |||
| 239 | st->ctrl_src); | |||
| 240 | ret = spi_sync(st->spi, &st->msg); | |||
| 241 | break; | |||
| 242 | default: | |||
| 243 | ret = -ENODEV; | |||
| 244 | } | |||
| 245 | mutex_unlock(&st->lock); | |||
| 246 | ||||
| 247 | error_ret: | |||
| 248 | return ret ? ret : len; | |||
| 249 | } | |||
| 250 | ||||
| 251 | /** | |||
| 252 | * see dds.h for further information | |||
| 253 | */ | |||
| 254 | ||||
| 255 | static IIO_DEV_ATTR_FREQ(0, 0, 0200, NULL, ad9832_write, AD9832_FREQ0HM); | |||
| 256 | static IIO_DEV_ATTR_FREQ(0, 1, 0200, NULL, ad9832_write, AD9832_FREQ1HM); | |||
| 257 | static IIO_DEV_ATTR_FREQSYMBOL(0, 0200, NULL, ad9832_write, AD9832_FREQ_SYM); | |||
| 258 | static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ | |||
| 259 | ||||
| 260 | static IIO_DEV_ATTR_PHASE(0, 0, 0200, NULL, ad9832_write, AD9832_PHASE0H); | |||
| 261 | static IIO_DEV_ATTR_PHASE(0, 1, 0200, NULL, ad9832_write, AD9832_PHASE1H); | |||
| 262 | static IIO_DEV_ATTR_PHASE(0, 2, 0200, NULL, ad9832_write, AD9832_PHASE2H); | |||
| 263 | static IIO_DEV_ATTR_PHASE(0, 3, 0200, NULL, ad9832_write, AD9832_PHASE3H); | |||
| 264 | static IIO_DEV_ATTR_PHASESYMBOL(0, 0200, NULL, | |||
| 265 | ad9832_write, AD9832_PHASE_SYM); | |||
| 266 | static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ | |||
| 267 | ||||
| 268 | static IIO_DEV_ATTR_PINCONTROL_EN(0, 0200, NULL, | |||
| 269 | ad9832_write, AD9832_PINCTRL_EN); | |||
| 270 | static IIO_DEV_ATTR_OUT_ENABLE(0, 0200, NULL, | |||
| 271 | ad9832_write, AD9832_OUTPUT_EN); | |||
| 272 | ||||
| 273 | static struct attribute *ad9832_attributes[] = { | |||
| 274 | &iio_dev_attr_out_altvoltage0_frequency0.dev_attr.attr, | |||
| 275 | &iio_dev_attr_out_altvoltage0_frequency1.dev_attr.attr, | |||
| 276 | &iio_const_attr_out_altvoltage0_frequency_scale.dev_attr.attr, | |||
| 277 | &iio_dev_attr_out_altvoltage0_phase0.dev_attr.attr, | |||
| 278 | &iio_dev_attr_out_altvoltage0_phase1.dev_attr.attr, | |||
| 279 | &iio_dev_attr_out_altvoltage0_phase2.dev_attr.attr, | |||
| 280 | &iio_dev_attr_out_altvoltage0_phase3.dev_attr.attr, | |||
| 281 | &iio_const_attr_out_altvoltage0_phase_scale.dev_attr.attr, | |||
| 282 | &iio_dev_attr_out_altvoltage0_pincontrol_en.dev_attr.attr, | |||
| 283 | &iio_dev_attr_out_altvoltage0_frequencysymbol.dev_attr.attr, | |||
| 284 | &iio_dev_attr_out_altvoltage0_phasesymbol.dev_attr.attr, | |||
| 285 | &iio_dev_attr_out_altvoltage0_out_enable.dev_attr.attr, | |||
| 286 | NULL, | |||
| 287 | }; | |||
| 288 | ||||
| 289 | static const struct attribute_group ad9832_attribute_group = { | |||
| 290 | .attrs = ad9832_attributes, | |||
| 291 | }; | |||
| 292 | ||||
| 293 | static const struct iio_info ad9832_info = { | |||
| 294 | .attrs = &ad9832_attribute_group, | |||
| 295 | }; | |||
| 296 | ||||
| 297 | #if defined(CONFIG_OF) | |||
| 298 | static struct ad9832_platform_data *ad9832_parse_dt(struct spi_device *spi) | |||
| 299 | { | |||
| 300 | struct ad9832_platform_data *pdata; | |||
| 301 | struct device_node *np = spi->dev.of_node; | |||
| 302 | unsigned int tmp; | |||
| 303 | ||||
| 304 | pdata = devm_kzalloc(&spi->dev, sizeof(*pdata), GFP_KERNEL); | |||
| 305 | if (!pdata) | |||
| 306 | return ERR_PTR(-ENOMEM); | |||
| 307 | ||||
| 308 | pdata->freq0 = 134000; | |||
| 309 | of_property_read_u32(np, "freq0", &tmp); | |||
| 310 | pdata->freq0=(unsigned int)tmp; | |||
| 311 | ||||
| 312 | pdata->freq1 = 134000; | |||
| 313 | of_property_read_u32(np, "freq1", &tmp); | |||
| 314 | pdata->freq1=(unsigned int)tmp; | |||
| 315 | ||||
| 316 | pdata->phase0 = 0; | |||
| 317 | of_property_read_u16(np, "phase0", &pdata->phase0); | |||
| 318 | ||||
| 319 | pdata->phase1 = 0; | |||
| 320 | of_property_read_u16(np, "phase1", &pdata->phase1); | |||
| 321 | ||||
| 322 | pdata->phase2 = 0; | |||
| 323 | of_property_read_u16(np, "phase1", &pdata->phase2); | |||
| 324 | ||||
| 325 | pdata->phase3 = 0; | |||
| 326 | of_property_read_u16(np, "phase1", &pdata->phase3); | |||
| 327 | ||||
| 328 | return pdata; | |||
| 329 | } | |||
| 330 | #else | |||
| 331 | static struct ad9832_platform_data *ad9832_parse_dt(struct spi_device *spi) | |||
| 332 | { | |||
| 333 | return NULL; | |||
| 334 | } | |||
| 335 | #endif | |||
| 336 | ||||
| 337 | static int ad9832_probe(struct spi_device *spi) | |||
| 338 | { | |||
| 339 | struct ad9832_platform_data *pdata = dev_get_platdata(&spi->dev); | |||
| 340 | struct iio_dev *indio_dev; | |||
| 341 | struct ad9832_state *st; | |||
| 342 | int ret; | |||
| 343 | ||||
| 344 | if (!pdata && spi->dev.of_node) { | |||
| 345 | pdata = ad9832_parse_dt(spi); | |||
| 346 | if (IS_ERR(pdata)) | |||
| 347 | return PTR_ERR(pdata); | |||
| 348 | } | |||
| 349 | ||||
| 350 | if (!pdata) { | |||
| 351 | dev_dbg(&spi->dev, "no platform data?\n"); | |||
| 352 | return -ENODEV; | |||
| 353 | } | |||
| 354 | ||||
| 355 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | |||
| 356 | if (!indio_dev) | |||
| 357 | return -ENOMEM; | |||
| 358 | ||||
| 359 | spi_set_drvdata(spi, indio_dev); | |||
| 360 | st = iio_priv(indio_dev); | |||
| 361 | ||||
| 362 | st->avdd = devm_regulator_get(&spi->dev, "avdd"); | |||
| 363 | if (IS_ERR(st->avdd)) | |||
| 364 | return PTR_ERR(st->avdd); | |||
| 365 | ||||
| 366 | ret = regulator_enable(st->avdd); | |||
| 367 | if (ret) { | |||
| 368 | dev_err(&spi->dev, "Failed to enable specified AVDD supply\n"); | |||
| 369 | return ret; | |||
| 370 | } | |||
| 371 | ||||
| 372 | st->dvdd = devm_regulator_get(&spi->dev, "dvdd"); | |||
| 373 | if (IS_ERR(st->dvdd)) { | |||
| 374 | ret = PTR_ERR(st->dvdd); | |||
| 375 | goto error_disable_avdd; | |||
| 376 | } | |||
| 377 | ||||
| 378 | ret = regulator_enable(st->dvdd); | |||
| 379 | if (ret) { | |||
| 380 | dev_err(&spi->dev, "Failed to enable specified DVDD supply\n"); | |||
| 381 | goto error_disable_avdd; | |||
| 382 | } | |||
| 383 | ||||
| 384 | st->mclk = devm_clk_get(&spi->dev, "mclk"); | |||
| 385 | if (IS_ERR(st->mclk)) { | |||
| 386 | ret = PTR_ERR(st->mclk); | |||
| 387 | goto error_disable_dvdd; | |||
| 388 | } | |||
| 389 | ||||
| 390 | ret = clk_prepare_enable(st->mclk); | |||
| 391 | if (ret < 0) | |||
| 392 | goto error_disable_dvdd; | |||
| 393 | ||||
| 394 | st->spi = spi; | |||
| 395 | mutex_init(&st->lock); | |||
| 396 | ||||
| 397 | indio_dev->name = spi_get_device_id(spi)->name; | |||
| 398 | indio_dev->info = &ad9832_info; | |||
| 399 | indio_dev->modes = INDIO_DIRECT_MODE; | |||
| 400 | ||||
| 401 | /* Setup default messages */ | |||
| 402 | ||||
| 403 | st->xfer.tx_buf = &st->data; | |||
| 404 | st->xfer.len = 2; | |||
| 405 | ||||
| 406 | spi_message_init(&st->msg); | |||
| 407 | spi_message_add_tail(&st->xfer, &st->msg); | |||
| 408 | ||||
| 409 | st->freq_xfer[0].tx_buf = &st->freq_data[0]; | |||
| 410 | st->freq_xfer[0].len = 2; | |||
| 411 | st->freq_xfer[0].cs_change = 1; | |||
| 412 | st->freq_xfer[1].tx_buf = &st->freq_data[1]; | |||
| 413 | st->freq_xfer[1].len = 2; | |||
| 414 | st->freq_xfer[1].cs_change = 1; | |||
| 415 | st->freq_xfer[2].tx_buf = &st->freq_data[2]; | |||
| 416 | st->freq_xfer[2].len = 2; | |||
| 417 | st->freq_xfer[2].cs_change = 1; | |||
| 418 | st->freq_xfer[3].tx_buf = &st->freq_data[3]; | |||
| 419 | st->freq_xfer[3].len = 2; | |||
| 420 | ||||
| 421 | spi_message_init(&st->freq_msg); | |||
| 422 | spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); | |||
| 423 | spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); | |||
| 424 | spi_message_add_tail(&st->freq_xfer[2], &st->freq_msg); | |||
| 425 | spi_message_add_tail(&st->freq_xfer[3], &st->freq_msg); | |||
| 426 | ||||
| 427 | st->phase_xfer[0].tx_buf = &st->phase_data[0]; | |||
| 428 | st->phase_xfer[0].len = 2; | |||
| 429 | st->phase_xfer[0].cs_change = 1; | |||
| 430 | st->phase_xfer[1].tx_buf = &st->phase_data[1]; | |||
| 431 | st->phase_xfer[1].len = 2; | |||
| 432 | ||||
| 433 | spi_message_init(&st->phase_msg); | |||
| 434 | spi_message_add_tail(&st->phase_xfer[0], &st->phase_msg); | |||
| 435 | spi_message_add_tail(&st->phase_xfer[1], &st->phase_msg); | |||
| 436 |
220124_AD9832driver/bcm2711-rpi-4-b.dts
| File was created | 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /dts-v1/; | |||
| 3 | #include "bcm2711.dtsi" | |||
| 4 | #include "bcm2835-rpi.dtsi" | |||
| 5 | ||||
| 6 | / { | |||
| 7 | compatible = "raspberrypi,4-model-b", "brcm,bcm2711"; | |||
| 8 | model = "Raspberry Pi 4 Model B"; | |||
| 9 | ||||
| 10 | chosen { | |||
| 11 | /* 8250 auxiliary UART instead of pl011 */ | |||
| 12 | stdout-path = "serial1:115200n8"; | |||
| 13 | }; | |||
| 14 | ||||
| 15 | /* Will be filled by the bootloader */ | |||
| 16 | memory@0 { | |||
| 17 | device_type = "memory"; | |||
| 18 | reg = <0 0 0>; | |||
| 19 | }; | |||
| 20 | ||||
| 21 | aliases { | |||
| 22 | emmc2bus = &emmc2bus; | |||
| 23 | ethernet0 = &genet; | |||
| 24 | pcie0 = &pcie0; | |||
| 25 | }; | |||
| 26 | ||||
| 27 | leds { | |||
| 28 | act { | |||
| 29 | gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; | |||
| 30 | }; | |||
| 31 | ||||
| 32 | pwr { | |||
| 33 | label = "PWR"; | |||
| 34 | gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; | |||
| 35 | default-state = "keep"; | |||
| 36 | linux,default-trigger = "default-on"; | |||
| 37 | }; | |||
| 38 | }; | |||
| 39 | ||||
| 40 | wifi_pwrseq: wifi-pwrseq { | |||
| 41 | compatible = "mmc-pwrseq-simple"; | |||
| 42 | reset-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; | |||
| 43 | }; | |||
| 44 | ||||
| 45 | sd_io_1v8_reg: sd_io_1v8_reg { | |||
| 46 | compatible = "regulator-gpio"; | |||
| 47 | regulator-name = "vdd-sd-io"; | |||
| 48 | regulator-min-microvolt = <1800000>; | |||
| 49 | regulator-max-microvolt = <3300000>; | |||
| 50 | regulator-boot-on; | |||
| 51 | regulator-always-on; | |||
| 52 | regulator-settling-time-us = <5000>; | |||
| 53 | gpios = <&expgpio 4 GPIO_ACTIVE_HIGH>; | |||
| 54 | states = <1800000 0x1 | |||
| 55 | 3300000 0x0>; | |||
| 56 | status = "okay"; | |||
| 57 | }; | |||
| 58 | }; | |||
| 59 | ||||
| 60 | &firmware { | |||
| 61 | expgpio: gpio { | |||
| 62 | compatible = "raspberrypi,firmware-gpio"; | |||
| 63 | gpio-controller; | |||
| 64 | #gpio-cells = <2>; | |||
| 65 | gpio-line-names = "BT_ON", | |||
| 66 | "WL_ON", | |||
| 67 | "PWR_LED_OFF", | |||
| 68 | "GLOBAL_RESET", | |||
| 69 | "VDD_SD_IO_SEL", | |||
| 70 | "CAM_GPIO", | |||
| 71 | "SD_PWR_ON", | |||
| 72 | "SD_OC_N"; | |||
| 73 | status = "okay"; | |||
| 74 | }; | |||
| 75 | }; | |||
| 76 | ||||
| 77 | &gpio { | |||
| 78 | /* | |||
| 79 | * Parts taken from rpi_SCH_4b_4p0_reduced.pdf and | |||
| 80 | * the official GPU firmware DT blob. | |||
| 81 | * | |||
| 82 | * Legend: | |||
| 83 | * "FOO" = GPIO line named "FOO" on the schematic | |||
| 84 | * "FOO_N" = GPIO line named "FOO" on schematic, active low | |||
| 85 | */ | |||
| 86 | gpio-line-names = "ID_SDA", | |||
| 87 | "ID_SCL", | |||
| 88 | "SDA1", | |||
| 89 | "SCL1", | |||
| 90 | "GPIO_GCLK", | |||
| 91 | "GPIO5", | |||
| 92 | "GPIO6", | |||
| 93 | "SPI_CE1_N", | |||
| 94 | "SPI_CE0_N", | |||
| 95 | "SPI_MISO", | |||
| 96 | "SPI_MOSI", | |||
| 97 | "SPI_SCLK", | |||
| 98 | "GPIO12", | |||
| 99 | "GPIO13", | |||
| 100 | /* Serial port */ | |||
| 101 | "TXD1", | |||
| 102 | "RXD1", | |||
| 103 | "GPIO16", | |||
| 104 | "GPIO17", | |||
| 105 | "GPIO18", | |||
| 106 | "GPIO19", | |||
| 107 | "GPIO20", | |||
| 108 | "GPIO21", | |||
| 109 | "GPIO22", | |||
| 110 | "GPIO23", | |||
| 111 | "GPIO24", | |||
| 112 | "GPIO25", | |||
| 113 | "GPIO26", | |||
| 114 | "GPIO27", | |||
| 115 | "RGMII_MDIO", | |||
| 116 | "RGMIO_MDC", | |||
| 117 | /* Used by BT module */ | |||
| 118 | "CTS0", | |||
| 119 | "RTS0", | |||
| 120 | "TXD0", | |||
| 121 | "RXD0", | |||
| 122 | /* Used by Wifi */ | |||
| 123 | "SD1_CLK", | |||
| 124 | "SD1_CMD", | |||
| 125 | "SD1_DATA0", | |||
| 126 | "SD1_DATA1", | |||
| 127 | "SD1_DATA2", | |||
| 128 | "SD1_DATA3", | |||
| 129 | /* Shared with SPI flash */ | |||
| 130 | "PWM0_MISO", | |||
| 131 | "PWM1_MOSI", | |||
| 132 | "STATUS_LED_G_CLK", | |||
| 133 | "SPIFLASH_CE_N", | |||
| 134 | "SDA0", | |||
| 135 | "SCL0", | |||
| 136 | "RGMII_RXCLK", | |||
| 137 | "RGMII_RXCTL", | |||
| 138 | "RGMII_RXD0", | |||
| 139 | "RGMII_RXD1", | |||
| 140 | "RGMII_RXD2", | |||
| 141 | "RGMII_RXD3", | |||
| 142 | "RGMII_TXCLK", | |||
| 143 | "RGMII_TXCTL", | |||
| 144 | "RGMII_TXD0", | |||
| 145 | "RGMII_TXD1", | |||
| 146 | "RGMII_TXD2", | |||
| 147 | "RGMII_TXD3"; | |||
| 148 | }; | |||
| 149 | ||||
| 150 | &pwm1 { | |||
| 151 | pinctrl-names = "default"; | |||
| 152 | pinctrl-0 = <&pwm1_0_gpio40 &pwm1_1_gpio41>; | |||
| 153 | status = "okay"; | |||
| 154 | }; | |||
| 155 | ||||
| 156 | /* SDHCI is used to control the SDIO for wireless */ | |||
| 157 | &sdhci { | |||
| 158 | #address-cells = <1>; | |||
| 159 | #size-cells = <0>; | |||
| 160 | pinctrl-names = "default"; | |||
| 161 | pinctrl-0 = <&emmc_gpio34>; | |||
| 162 | bus-width = <4>; | |||
| 163 | non-removable; | |||
| 164 | mmc-pwrseq = <&wifi_pwrseq>; | |||
| 165 | status = "okay"; | |||
| 166 | ||||
| 167 | brcmf: wifi@1 { | |||
| 168 | reg = <1>; | |||
| 169 | compatible = "brcm,bcm4329-fmac"; | |||
| 170 | }; | |||
| 171 | }; | |||
| 172 | ||||
| 173 | /* EMMC2 is used to drive the SD card */ | |||
| 174 | &emmc2 { | |||
| 175 | vqmmc-supply = <&sd_io_1v8_reg>; | |||
| 176 | broken-cd; | |||
| 177 | status = "okay"; | |||
| 178 | }; | |||
| 179 | ||||
| 180 | &genet { | |||
| 181 | phy-handle = <&phy1>; | |||
| 182 | phy-mode = "rgmii-rxid"; | |||
| 183 | status = "okay"; | |||
| 184 | }; | |||
| 185 | ||||
| 186 | &genet_mdio { | |||
| 187 | phy1: ethernet-phy@1 { | |||
| 188 | /* No PHY interrupt */ | |||
| 189 | reg = <0x1>; | |||
| 190 | }; | |||
| 191 | }; | |||
| 192 | ||||
| 193 | /* uart0 communicates with the BT module */ | |||
| 194 | &uart0 { | |||
| 195 | pinctrl-names = "default"; | |||
| 196 | pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32>; | |||
| 197 | uart-has-rtscts; | |||
| 198 | status = "okay"; | |||
| 199 | ||||
| 200 | bluetooth { | |||
| 201 | compatible = "brcm,bcm43438-bt"; | |||
| 202 | max-speed = <2000000>; | |||
| 203 | shutdown-gpios = <&expgpio 0 GPIO_ACTIVE_HIGH>; | |||
| 204 | }; | |||
| 205 | }; | |||
| 206 | ||||
| 207 | /* uart1 is mapped to the pin header */ | |||
| 208 | &uart1 { | |||
| 209 | pinctrl-names = "default"; | |||
| 210 | pinctrl-0 = <&uart1_gpio14>; | |||
| 211 | status = "okay"; | |||
| 212 | }; | |||
| 213 | ||||
| 214 | &vchiq { | |||
| 215 | interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; | |||
| 216 | }; | |||
| 217 | ||||
| 218 | // ============================================= | |||
| 219 | // Downstream rpi- changes | |||
| 220 | ||||
| 221 | #include "bcm270x.dtsi" | |||
| 222 | #include "bcm271x-rpi-bt.dtsi" | |||
| 223 | ||||
| 224 | / { | |||
| 225 | soc { | |||
| 226 | /delete-node/ pixelvalve@7e807000; | |||
| 227 | /delete-node/ hdmi@7e902000; | |||
| 228 | }; | |||
| 229 | }; | |||
| 230 | ||||
| 231 | #include "bcm2711-rpi.dtsi" | |||
| 232 | #include "bcm283x-rpi-csi1-2lane.dtsi" | |||
| 233 | #include "bcm283x-rpi-i2c0mux_0_44.dtsi" | |||
| 234 | ||||
| 235 | / { | |||
| 236 | chosen { | |||
| 237 | bootargs = "coherent_pool=1M 8250.nr_uarts=1 snd_bcm2835.enable_compat_alsa=0 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_headphones=1"; | |||
| 238 | }; | |||
| 239 | ||||
| 240 | aliases { | |||
| 241 | serial0 = &uart1; | |||
| 242 | serial1 = &uart0; | |||
| 243 | mmc0 = &emmc2; | |||
| 244 | mmc1 = &mmcnr; | |||
| 245 | mmc2 = &sdhost; | |||
| 246 | /delete-property/ i2c2; | |||
| 247 | i2c3 = &i2c3; | |||
| 248 | i2c4 = &i2c4; | |||
| 249 | i2c5 = &i2c5; | |||
| 250 | i2c6 = &i2c6; | |||
| 251 | /delete-property/ intc; | |||
| 252 | }; | |||
| 253 | ||||
| 254 | vcc: fixedregulator@0 { | |||
| 255 | compatible = "regulator-fixed"; | |||
| 256 | regulator-name = "fixed-supply"; | |||
| 257 | regulator-min-microvolt = <2500000>; | |||
| 258 | regulator-max-microvolt = <2500000>; | |||
| 259 | regulator-boot-on; | |||
| 260 | }; | |||
| 261 | ||||
| 262 | osc: oscillator { | |||
| 263 | #clock-cells = <0>; | |||
| 264 | compatible = "fixed-clock"; | |||
| 265 | clock-frequency = <25000000>; | |||
| 266 | clock-output-names = "mclk"; | |||
| 267 | }; | |||
| 268 | ||||
| 269 | /delete-node/ wifi-pwrseq; | |||
| 270 | }; | |||
| 271 | ||||
| 272 | &mmcnr { | |||
| 273 | pinctrl-names = "default"; | |||
| 274 | pinctrl-0 = <&sdio_pins>; | |||
| 275 | bus-width = <4>; | |||
| 276 | status = "okay"; | |||
| 277 | }; | |||
| 278 | ||||
| 279 | &uart0 { | |||
| 280 | pinctrl-0 = <&uart0_pins &bt_pins>; | |||
| 281 | status = "okay"; | |||
| 282 | }; | |||
| 283 | ||||
| 284 | &uart1 { | |||
| 285 | pinctrl-0 = <&uart1_pins>; | |||
| 286 | }; | |||
| 287 | ||||
| 288 | &spi0 { | |||
| 289 | pinctrl-names = "default"; | |||
| 290 | pinctrl-0 = <&spi0_pins &spi0_cs_pins>; | |||
| 291 | cs-gpios = <&gpio 8 1>, <&gpio 7 1>; | |||
| 292 | status = "okay"; | |||
| 293 | ||||
| 294 | ad9832@0{ | |||
| 295 | #clock-cells = <0>; | |||
| 296 | compatible = "ad9832"; | |||
| 297 | reg = <0>; | |||
| 298 | spi-max-frequency = <1000000>; | |||
| 299 | spi-cpol; | |||
| 300 | //spi-cpha; // mode 2 => CPHA = CPOL = 1 | |||
| 301 | clocks = <&osc>; | |||
| 302 | clock-names="mclk"; | |||
| 303 | vcc-supply = <&vcc>; | |||
| 304 | }; | |||
| 305 | ||||
| 306 | //spidev0: spidev@0{ | |||
| 307 | // compatible = "spidev"; | |||
| 308 | // reg = <0>; /* CE0 */ | |||
| 309 | // #address-cells = <1>; | |||
| 310 | // #size-cells = <0>; | |||
| 311 | // spi-max-frequency = <125000000>; | |||
| 312 | //}; | |||
| 313 | ||||
| 314 | //spidev1: spidev@1{ | |||
| 315 | // compatible = "spidev"; | |||
| 316 | // reg = <1>; /* CE1 */ | |||
| 317 | // #address-cells = <1>; | |||
| 318 | // #size-cells = <0>; | |||
| 319 | // spi-max-frequency = <125000000>; | |||
| 320 | //}; | |||
| 321 | }; | |||
| 322 | ||||
| 323 | &gpio { | |||
| 324 | spi0_pins: spi0_pins { | |||
| 325 | brcm,pins = <9 10 11>; | |||
| 326 | brcm,function = <BCM2835_FSEL_ALT0>; | |||
| 327 | }; | |||
| 328 | ||||
| 329 | spi0_cs_pins: spi0_cs_pins { | |||
| 330 | brcm,pins = <8 7>; | |||
| 331 | brcm,function = <BCM2835_FSEL_GPIO_OUT>; | |||
| 332 | }; | |||
| 333 | ||||
| 334 | spi3_pins: spi3_pins { | |||
| 335 | brcm,pins = <1 2 3>; | |||
| 336 | brcm,function = <BCM2835_FSEL_ALT3>; | |||
| 337 | }; | |||
| 338 | ||||
| 339 | spi3_cs_pins: spi3_cs_pins { | |||
| 340 | brcm,pins = <0 24>; | |||
| 341 | brcm,function = <BCM2835_FSEL_GPIO_OUT>; | |||
| 342 | }; | |||
| 343 | ||||
| 344 | spi4_pins: spi4_pins { | |||
| 345 | brcm,pins = <5 6 7>; | |||
| 346 | brcm,function = <BCM2835_FSEL_ALT3>; | |||
| 347 | }; | |||
| 348 | ||||
| 349 | spi4_cs_pins: spi4_cs_pins { | |||
| 350 | brcm,pins = <4 25>; | |||
| 351 | brcm,function = <BCM2835_FSEL_GPIO_OUT>; | |||
| 352 | }; | |||
| 353 | ||||
| 354 | spi5_pins: spi5_pins { | |||
| 355 | brcm,pins = <13 14 15>; | |||
| 356 | brcm,function = <BCM2835_FSEL_ALT3>; | |||
| 357 | }; | |||
| 358 | ||||
| 359 | spi5_cs_pins: spi5_cs_pins { | |||
| 360 | brcm,pins = <12 26>; | |||
| 361 | brcm,function = <BCM2835_FSEL_GPIO_OUT>; | |||
| 362 | }; | |||
| 363 | ||||
| 364 | spi6_pins: spi6_pins { | |||
| 365 | brcm,pins = <19 20 21>; | |||
| 366 | brcm,function = <BCM2835_FSEL_ALT3>; | |||
| 367 | }; | |||
| 368 | ||||
| 369 | spi6_cs_pins: spi6_cs_pins { | |||
| 370 | brcm,pins = <18 27>; | |||
| 371 | brcm,function = <BCM2835_FSEL_GPIO_OUT>; | |||
| 372 | }; | |||
| 373 | ||||
| 374 | i2c0_pins: i2c0 { | |||
| 375 | brcm,pins = <0 1>; | |||
| 376 | brcm,function = <BCM2835_FSEL_ALT0>; | |||
| 377 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 378 | }; | |||
| 379 | ||||
| 380 | i2c1_pins: i2c1 { | |||
| 381 | brcm,pins = <2 3>; | |||
| 382 | brcm,function = <BCM2835_FSEL_ALT0>; | |||
| 383 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 384 | }; | |||
| 385 | ||||
| 386 | i2c3_pins: i2c3 { | |||
| 387 | brcm,pins = <4 5>; | |||
| 388 | brcm,function = <BCM2835_FSEL_ALT5>; | |||
| 389 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 390 | }; | |||
| 391 | ||||
| 392 | i2c4_pins: i2c4 { | |||
| 393 | brcm,pins = <8 9>; | |||
| 394 | brcm,function = <BCM2835_FSEL_ALT5>; | |||
| 395 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 396 | }; | |||
| 397 | ||||
| 398 | i2c5_pins: i2c5 { | |||
| 399 | brcm,pins = <12 13>; | |||
| 400 | brcm,function = <BCM2835_FSEL_ALT5>; | |||
| 401 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 402 | }; | |||
| 403 | ||||
| 404 | i2c6_pins: i2c6 { | |||
| 405 | brcm,pins = <22 23>; | |||
| 406 | brcm,function = <BCM2835_FSEL_ALT5>; | |||
| 407 | brcm,pull = <BCM2835_PUD_UP>; | |||
| 408 | }; | |||
| 409 | ||||
| 410 | i2s_pins: i2s { | |||
| 411 | brcm,pins = <18 19 20 21>; | |||
| 412 | brcm,function = <BCM2835_FSEL_ALT0>; | |||
| 413 | }; | |||
| 414 | ||||
| 415 | sdio_pins: sdio_pins { | |||
| 416 | brcm,pins = <34 35 36 37 38 39>; | |||
| 417 | brcm,function = <BCM2835_FSEL_ALT3>; // alt3 = SD1 | |||
| 418 | brcm,pull = <0 2 2 2 2 2>; | |||
| 419 | }; | |||
| 420 | ||||
| 421 | bt_pins: bt_pins { | |||
| 422 | brcm,pins = "-"; // non-empty to keep btuart happy, //4 = 0 | |||
| 423 | // to fool pinctrl | |||
| 424 | brcm,function = <0>; | |||
| 425 | brcm,pull = <2>; | |||
| 426 | }; | |||
| 427 | ||||
| 428 | uart0_pins: uart0_pins { | |||
| 429 | brcm,pins = <32 33>; | |||
| 430 | brcm,function = <BCM2835_FSEL_ALT3>; | |||
| 431 | brcm,pull = <0 2>; | |||
| 432 | }; | |||
| 433 | ||||
| 434 | uart1_pins: uart1_pins { | |||
| 435 | brcm,pins; | |||
| 436 | brcm,function; | |||
| 437 | brcm,pull; | |||
| 438 | }; | |||
| 439 | ||||
| 440 | uart2_pins: uart2_pins { | |||
| 441 | brcm,pins = <0 1>; | |||
| 442 | brcm,function = <BCM2835_FSEL_ALT4>; | |||
| 443 | brcm,pull = <0 2>; | |||
| 444 | }; | |||
| 445 | ||||
| 446 | uart3_pins: uart3_pins { | |||
| 447 | brcm,pins = <4 5>; | |||
| 448 | brcm,function = <BCM2835_FSEL_ALT4>; | |||
| 449 | brcm,pull = <0 2>; | |||
| 450 | }; | |||
| 451 | ||||
| 452 | uart4_pins: uart4_pins { | |||
| 453 | brcm,pins = <8 9>; | |||
| 454 | brcm,function = <BCM2835_FSEL_ALT4>; | |||
| 455 | brcm,pull = <0 2>; | |||
| 456 | }; | |||
| 457 | ||||
| 458 | uart5_pins: uart5_pins { | |||
| 459 | brcm,pins = <12 13>; | |||
| 460 | brcm,function = <BCM2835_FSEL_ALT4>; | |||
| 461 | brcm,pull = <0 2>; | |||
| 462 | }; | |||
| 463 | }; | |||
| 464 | ||||
| 465 | &i2c0if { | |||
| 466 | clock-frequency = <100000>; | |||
| 467 | }; | |||
| 468 | ||||
| 469 | &i2c1 { | |||
| 470 | pinctrl-names = "default"; | |||
| 471 | pinctrl-0 = <&i2c1_pins>; | |||
| 472 | clock-frequency = <100000>; | |||
| 473 | }; | |||
| 474 | ||||
| 475 | &i2s { | |||
| 476 | pinctrl-names = "default"; | |||
| 477 | pinctrl-0 = <&i2s_pins>; | |||
| 478 | }; | |||
| 479 | ||||
| 480 | / { | |||
| 481 | __overrides__ { | |||
| 482 | /delete-property/ i2c2_baudrate; | |||
| 483 | /delete-property/ i2c2_iknowwhatimdoing; | |||
| 484 | }; | |||
| 485 | }; | |||
| 486 | ||||
| 487 | &firmwarekms { | |||
| 488 | compatible = "raspberrypi,rpi-firmware-kms-2711"; | |||
| 489 | }; | |||
| 490 | ||||
| 491 | // ============================================= | |||
| 492 | // Board specific stuff here | |||
| 493 | ||||
| 494 | / { | |||
| 495 | sd_vcc_reg: sd_vcc_reg { | |||
| 496 | compatible = "regulator-fixed"; | |||
| 497 | regulator-name = "vcc-sd"; | |||
| 498 | regulator-min-microvolt = <3300000>; | |||
| 499 | regulator-max-microvolt = <3300000>; | |||
| 500 | regulator-boot-on; | |||
| 501 | enable-active-high; | |||
| 502 | gpio = <&expgpio 6 GPIO_ACTIVE_HIGH>; | |||
| 503 | }; | |||
| 504 | }; | |||
| 505 | ||||
| 506 | &sdhost { | |||
| 507 | status = "disabled"; | |||
| 508 | }; | |||
| 509 | ||||
| 510 | &emmc2 { | |||
| 511 | vmmc-supply = <&sd_vcc_reg>; | |||
| 512 | }; | |||
| 513 | ||||
| 514 | &phy1 { | |||
| 515 | led-modes = <0x00 0x08>; /* link/activity link */ |