// SPDX-License-Identifier: GPL-2.0-only #include #include #include #include #include #include #include "core.h" #include "synth.h" /** * zl3073x_synth_state_fetch - fetch synth state from hardware * @zldev: pointer to zl3073x_dev structure * @index: synth index to fetch state for * * Function fetches state of the given synthesizer from the hardware and * stores it for later use. * * Return: 0 on success, <0 on error */ int zl3073x_synth_state_fetch(struct zl3073x_dev *zldev, u8 index) { struct zl3073x_synth *synth = &zldev->synth[index]; int rc; /* Read synth control register */ rc = zl3073x_read_u8(zldev, ZL_REG_SYNTH_CTRL(index), &synth->ctrl); if (rc) return rc; guard(mutex)(&zldev->multiop_lock); /* Read synth configuration */ rc = zl3073x_mb_op(zldev, ZL_REG_SYNTH_MB_SEM, ZL_SYNTH_MB_SEM_RD, ZL_REG_SYNTH_MB_MASK, BIT(index)); if (rc) return rc; /* The output frequency is determined by the following formula: * base * multiplier * numerator / denominator * * Read registers with these values */ rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_BASE, &synth->freq_base); if (rc) return rc; rc = zl3073x_read_u32(zldev, ZL_REG_SYNTH_FREQ_MULT, &synth->freq_mult); if (rc) return rc; rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_M, &synth->freq_m); if (rc) return rc; rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_N, &synth->freq_n); if (rc) return rc; /* Check denominator for zero to avoid div by 0 */ if (!synth->freq_n) { dev_err(zldev->dev, "Zero divisor for SYNTH%u retrieved from device\n", index); return -EINVAL; } dev_dbg(zldev->dev, "SYNTH%u frequency: %u Hz\n", index, zl3073x_synth_freq_get(synth)); return rc; } /** * zl3073x_synth_state_get - get current synth state * @zldev: pointer to zl3073x_dev structure * @index: synth index to get state for * * Return: pointer to given synth state */ const struct zl3073x_synth *zl3073x_synth_state_get(struct zl3073x_dev *zldev, u8 index) { return &zldev->synth[index]; }