1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/bitfield.h> 4 #include <linux/cleanup.h> 5 #include <linux/dev_printk.h> 6 #include <linux/string.h> 7 #include <linux/string_choices.h> 8 #include <linux/types.h> 9 10 #include "core.h" 11 #include "synth.h" 12 13 /** 14 * zl3073x_synth_state_fetch - fetch synth state from hardware 15 * @zldev: pointer to zl3073x_dev structure 16 * @index: synth index to fetch state for 17 * 18 * Function fetches state of the given synthesizer from the hardware and 19 * stores it for later use. 20 * 21 * Return: 0 on success, <0 on error 22 */ 23 int zl3073x_synth_state_fetch(struct zl3073x_dev *zldev, u8 index) 24 { 25 struct zl3073x_synth *synth = &zldev->synth[index]; 26 int rc; 27 28 /* Read synth control register */ 29 rc = zl3073x_read_u8(zldev, ZL_REG_SYNTH_CTRL(index), &synth->ctrl); 30 if (rc) 31 return rc; 32 33 guard(mutex)(&zldev->multiop_lock); 34 35 /* Read synth configuration */ 36 rc = zl3073x_mb_op(zldev, ZL_REG_SYNTH_MB_SEM, ZL_SYNTH_MB_SEM_RD, 37 ZL_REG_SYNTH_MB_MASK, BIT(index)); 38 if (rc) 39 return rc; 40 41 /* The output frequency is determined by the following formula: 42 * base * multiplier * numerator / denominator 43 * 44 * Read registers with these values 45 */ 46 rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_BASE, &synth->freq_base); 47 if (rc) 48 return rc; 49 50 rc = zl3073x_read_u32(zldev, ZL_REG_SYNTH_FREQ_MULT, &synth->freq_mult); 51 if (rc) 52 return rc; 53 54 rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_M, &synth->freq_m); 55 if (rc) 56 return rc; 57 58 rc = zl3073x_read_u16(zldev, ZL_REG_SYNTH_FREQ_N, &synth->freq_n); 59 if (rc) 60 return rc; 61 62 /* Check denominator for zero to avoid div by 0 */ 63 if (!synth->freq_n) { 64 dev_err(zldev->dev, 65 "Zero divisor for SYNTH%u retrieved from device\n", 66 index); 67 return -EINVAL; 68 } 69 70 dev_dbg(zldev->dev, "SYNTH%u frequency: %u Hz\n", index, 71 zl3073x_synth_freq_get(synth)); 72 73 return rc; 74 } 75 76 /** 77 * zl3073x_synth_state_get - get current synth state 78 * @zldev: pointer to zl3073x_dev structure 79 * @index: synth index to get state for 80 * 81 * Return: pointer to given synth state 82 */ 83 const struct zl3073x_synth *zl3073x_synth_state_get(struct zl3073x_dev *zldev, 84 u8 index) 85 { 86 return &zldev->synth[index]; 87 } 88