Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: amplifiers: hmc425a: move conversion logic

Move gain-dB<->code conversion logic from read_raw and write_raw to
chip_info callbacks.

Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
Reviewed-by: Nuno Sa <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20240220153553.2432-2-mitrutzceclan@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Dumitru Ceclan and committed by
Jonathan Cameron
2edb2257 ff96eb45

+83 -42
+83 -42
drivers/iio/amplifiers/hmc425a.c
··· 34 34 int gain_min; 35 35 int gain_max; 36 36 int default_gain; 37 + 38 + int (*gain_dB_to_code)(int gain, int *code); 39 + int (*code_to_gain_dB)(int code, int *val, int *val2); 37 40 }; 38 41 39 42 struct hmc425a_state { ··· 46 43 enum hmc425a_type type; 47 44 u32 gain; 48 45 }; 46 + 47 + static int gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code) 48 + { 49 + struct hmc425a_chip_info *inf = st->chip_info; 50 + int gain; 51 + 52 + if (val < 0) 53 + gain = (val * 1000) - (val2 / 1000); 54 + else 55 + gain = (val * 1000) + (val2 / 1000); 56 + 57 + if (gain > inf->gain_max || gain < inf->gain_min) 58 + return -EINVAL; 59 + 60 + return st->chip_info->gain_dB_to_code(gain, code); 61 + } 62 + 63 + static int hmc425a_gain_dB_to_code(int gain, int *code) 64 + { 65 + *code = ~((abs(gain) / 500) & 0x3F); 66 + return 0; 67 + } 68 + 69 + static int hmc540s_gain_dB_to_code(int gain, int *code) 70 + { 71 + *code = ~((abs(gain) / 1000) & 0xF); 72 + return 0; 73 + } 74 + 75 + static int adrf5740_gain_dB_to_code(int gain, int *code) 76 + { 77 + int temp = (abs(gain) / 2000) & 0xF; 78 + 79 + /* Bit [0-3]: 2dB 4dB 8dB 8dB */ 80 + *code = temp & BIT(3) ? temp | BIT(2) : temp; 81 + return 0; 82 + } 83 + 84 + static int code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2) 85 + { 86 + return st->chip_info->code_to_gain_dB(st->gain, val, val2); 87 + } 88 + 89 + static int hmc425a_code_to_gain_dB(int code, int *val, int *val2) 90 + { 91 + *val = (~code * -500) / 1000; 92 + *val2 = ((~code * -500) % 1000) * 1000; 93 + return 0; 94 + } 95 + 96 + static int hmc540s_code_to_gain_dB(int code, int *val, int *val2) 97 + { 98 + *val = (~code * -1000) / 1000; 99 + *val2 = ((~code * -1000) % 1000) * 1000; 100 + return 0; 101 + } 102 + 103 + static int adrf5740_code_to_gain_dB(int code, int *val, int *val2) 104 + { 105 + /* 106 + * Bit [0-3]: 2dB 4dB 8dB 8dB 107 + * When BIT(3) is set, unset BIT(2) and use 3 as double the place value 108 + */ 109 + code = code & BIT(3) ? code & ~BIT(2) : code; 110 + *val = (code * -2000) / 1000; 111 + *val2 = ((code * -2000) % 1000) * 1000; 112 + return 0; 113 + } 49 114 50 115 static int hmc425a_write(struct iio_dev *indio_dev, u32 value) 51 116 { ··· 132 61 int *val2, long m) 133 62 { 134 63 struct hmc425a_state *st = iio_priv(indio_dev); 135 - int code, gain = 0; 136 64 int ret; 137 65 138 66 mutex_lock(&st->lock); 139 67 switch (m) { 140 68 case IIO_CHAN_INFO_HARDWAREGAIN: 141 - code = st->gain; 142 - 143 - switch (st->type) { 144 - case ID_HMC425A: 145 - gain = ~code * -500; 69 + ret = code_to_gain_dB(st, val, val2); 70 + if (ret) 146 71 break; 147 - case ID_HMC540S: 148 - gain = ~code * -1000; 149 - break; 150 - case ID_ADRF5740: 151 - code = code & BIT(3) ? code & ~BIT(2) : code; 152 - gain = code * -2000; 153 - break; 154 - } 155 - 156 - *val = gain / 1000; 157 - *val2 = (gain % 1000) * 1000; 158 - 159 72 ret = IIO_VAL_INT_PLUS_MICRO_DB; 160 73 break; 161 74 default: ··· 155 100 int val2, long mask) 156 101 { 157 102 struct hmc425a_state *st = iio_priv(indio_dev); 158 - struct hmc425a_chip_info *inf = st->chip_info; 159 - int code = 0, gain; 160 - int ret; 161 - 162 - if (val < 0) 163 - gain = (val * 1000) - (val2 / 1000); 164 - else 165 - gain = (val * 1000) + (val2 / 1000); 166 - 167 - if (gain > inf->gain_max || gain < inf->gain_min) 168 - return -EINVAL; 169 - 170 - switch (st->type) { 171 - case ID_HMC425A: 172 - code = ~((abs(gain) / 500) & 0x3F); 173 - break; 174 - case ID_HMC540S: 175 - code = ~((abs(gain) / 1000) & 0xF); 176 - break; 177 - case ID_ADRF5740: 178 - code = (abs(gain) / 2000) & 0xF; 179 - code = code & BIT(3) ? code | BIT(2) : code; 180 - break; 181 - } 103 + int code = 0, ret; 182 104 183 105 mutex_lock(&st->lock); 184 106 switch (mask) { 185 107 case IIO_CHAN_INFO_HARDWAREGAIN: 108 + ret = gain_dB_to_code(st, val, val2, &code); 109 + if (ret) 110 + break; 186 111 st->gain = code; 187 112 188 113 ret = hmc425a_write(indio_dev, st->gain); ··· 224 189 .gain_min = -31500, 225 190 .gain_max = 0, 226 191 .default_gain = -0x40, /* set default gain -31.5db*/ 192 + .gain_dB_to_code = hmc425a_gain_dB_to_code, 193 + .code_to_gain_dB = hmc425a_code_to_gain_dB, 227 194 }, 228 195 [ID_HMC540S] = { 229 196 .name = "hmc540s", ··· 235 198 .gain_min = -15000, 236 199 .gain_max = 0, 237 200 .default_gain = -0x10, /* set default gain -15.0db*/ 201 + .gain_dB_to_code = hmc540s_gain_dB_to_code, 202 + .code_to_gain_dB = hmc540s_code_to_gain_dB, 238 203 }, 239 204 [ID_ADRF5740] = { 240 205 .name = "adrf5740", ··· 246 207 .gain_min = -22000, 247 208 .gain_max = 0, 248 209 .default_gain = 0xF, /* set default gain -22.0db*/ 210 + .gain_dB_to_code = adrf5740_gain_dB_to_code, 211 + .code_to_gain_dB = adrf5740_code_to_gain_dB, 249 212 }, 250 213 }; 251 214