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: adc: rzg2l_adc: Prepare for the addition of RZ/G3S support

The ADC IP available on the RZ/G3S differs slightly from the one found on
the RZ/G2L. The identified differences are as follows:
- different number of channels (one being used for temperature conversion);
consequently, various registers differ
- different default sampling periods
- the RZ/G3S variant lacks the ADVIC register.

To accommodate these differences, the rzg2l_adc driver has been updated by
introducing the struct rzg2l_adc_hw_params, which encapsulates the
hardware-specific differences between the IP variants. A pointer to an
object of type struct rzg2l_adc_hw_params is embedded in
struct rzg2l_adc_data.

Additionally, the completion member of struct rzg2l_adc_data was relocated
to avoid potential padding, if any.

The code has been adjusted to utilize hardware-specific parameters stored
in the new structure instead of relying on plain macros.

The check of chan->channel in rzg2l_adc_read_raw() function, against the
driver specific mask was removed as the subsystem should have already
been done this before reaching the rzg2l_adc_read_raw() function. Along
with it the local variable ch was dropped as chan->channel could be used
instead.

Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Link: https://patch.msgid.link/20241206111337.726244-10-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Claudiu Beznea and committed by
Jonathan Cameron
a259a846 d7c3e346

+59 -28
+59 -28
drivers/iio/adc/rzg2l_adc.c
··· 33 33 #define RZG2L_ADM1_MS BIT(2) 34 34 #define RZG2L_ADM1_BS BIT(4) 35 35 #define RZG2L_ADM1_EGA_MASK GENMASK(13, 12) 36 - #define RZG2L_ADM2_CHSEL_MASK GENMASK(7, 0) 37 36 #define RZG2L_ADM3_ADIL_MASK GENMASK(31, 24) 38 37 #define RZG2L_ADM3_ADCMP_MASK GENMASK(23, 16) 39 - #define RZG2L_ADM3_ADCMP_E FIELD_PREP(RZG2L_ADM3_ADCMP_MASK, 0xe) 40 - #define RZG2L_ADM3_ADSMP_MASK GENMASK(15, 0) 41 38 42 39 #define RZG2L_ADINT 0x20 43 - #define RZG2L_ADINT_INTEN_MASK GENMASK(7, 0) 44 40 #define RZG2L_ADINT_CSEEN BIT(16) 45 41 #define RZG2L_ADINT_INTS BIT(31) 46 42 47 43 #define RZG2L_ADSTS 0x24 48 44 #define RZG2L_ADSTS_CSEST BIT(16) 49 - #define RZG2L_ADSTS_INTST_MASK GENMASK(7, 0) 50 45 51 46 #define RZG2L_ADIVC 0x28 52 47 #define RZG2L_ADIVC_DIVADC_MASK GENMASK(8, 0) ··· 52 57 #define RZG2L_ADCR(n) (0x30 + ((n) * 0x4)) 53 58 #define RZG2L_ADCR_AD_MASK GENMASK(11, 0) 54 59 55 - #define RZG2L_ADSMP_DEFAULT_SAMPLING 0x578 56 - 57 60 #define RZG2L_ADC_MAX_CHANNELS 8 58 - #define RZG2L_ADC_CHN_MASK 0x7 59 61 #define RZG2L_ADC_TIMEOUT usecs_to_jiffies(1 * 4) 62 + 63 + /** 64 + * struct rzg2l_adc_hw_params - ADC hardware specific parameters 65 + * @default_adsmp: default ADC sampling period (see ADM3 register) 66 + * @adsmp_mask: ADC sampling period mask (see ADM3 register) 67 + * @adint_inten_mask: conversion end interrupt mask (see ADINT register) 68 + * @default_adcmp: default ADC cmp (see ADM3 register) 69 + * @num_channels: number of supported channels 70 + * @adivc: specifies if ADVIC register is available 71 + */ 72 + struct rzg2l_adc_hw_params { 73 + u16 default_adsmp; 74 + u16 adsmp_mask; 75 + u16 adint_inten_mask; 76 + u8 default_adcmp; 77 + u8 num_channels; 78 + bool adivc; 79 + }; 60 80 61 81 struct rzg2l_adc_data { 62 82 const struct iio_chan_spec *channels; ··· 82 72 void __iomem *base; 83 73 struct reset_control *presetn; 84 74 struct reset_control *adrstn; 85 - struct completion completion; 86 75 const struct rzg2l_adc_data *data; 76 + const struct rzg2l_adc_hw_params *hw_params; 77 + struct completion completion; 87 78 struct mutex lock; 88 79 u16 last_val[RZG2L_ADC_MAX_CHANNELS]; 89 80 }; ··· 165 154 166 155 static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch) 167 156 { 157 + const struct rzg2l_adc_hw_params *hw_params = adc->hw_params; 168 158 u32 reg; 169 159 170 160 if (rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_ADBSY) ··· 175 163 176 164 /* Select analog input channel subjected to conversion. */ 177 165 reg = rzg2l_adc_readl(adc, RZG2L_ADM(2)); 178 - reg &= ~RZG2L_ADM2_CHSEL_MASK; 166 + reg &= ~GENMASK(hw_params->num_channels - 1, 0); 179 167 reg |= BIT(ch); 180 168 rzg2l_adc_writel(adc, RZG2L_ADM(2), reg); 181 169 ··· 187 175 */ 188 176 reg = rzg2l_adc_readl(adc, RZG2L_ADINT); 189 177 reg &= ~RZG2L_ADINT_INTS; 190 - reg &= ~RZG2L_ADINT_INTEN_MASK; 178 + reg &= ~hw_params->adint_inten_mask; 191 179 reg |= (RZG2L_ADINT_CSEEN | BIT(ch)); 192 180 rzg2l_adc_writel(adc, RZG2L_ADINT, reg); 193 181 ··· 196 184 197 185 static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch) 198 186 { 187 + const struct rzg2l_adc_hw_params *hw_params = adc->hw_params; 199 188 struct device *dev = indio_dev->dev.parent; 200 189 int ret; 201 190 ··· 214 201 215 202 if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) { 216 203 rzg2l_adc_writel(adc, RZG2L_ADINT, 217 - rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK); 204 + rzg2l_adc_readl(adc, RZG2L_ADINT) & ~hw_params->adint_inten_mask); 218 205 ret = -ETIMEDOUT; 219 206 } 220 207 ··· 232 219 { 233 220 struct rzg2l_adc *adc = iio_priv(indio_dev); 234 221 int ret; 235 - u8 ch; 236 222 237 223 switch (mask) { 238 224 case IIO_CHAN_INFO_RAW: { ··· 240 228 241 229 guard(mutex)(&adc->lock); 242 230 243 - ch = chan->channel & RZG2L_ADC_CHN_MASK; 244 - ret = rzg2l_adc_conversion(indio_dev, adc, ch); 231 + ret = rzg2l_adc_conversion(indio_dev, adc, chan->channel); 245 232 if (ret) 246 233 return ret; 247 234 248 - *val = adc->last_val[ch]; 235 + *val = adc->last_val[chan->channel]; 249 236 250 237 return IIO_VAL_INT; 251 238 } ··· 269 258 static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id) 270 259 { 271 260 struct rzg2l_adc *adc = dev_id; 261 + const struct rzg2l_adc_hw_params *hw_params = adc->hw_params; 272 262 unsigned long intst; 273 263 u32 reg; 274 264 int ch; ··· 282 270 return IRQ_HANDLED; 283 271 } 284 272 285 - intst = reg & RZG2L_ADSTS_INTST_MASK; 273 + intst = reg & GENMASK(hw_params->num_channels - 1, 0); 286 274 if (!intst) 287 275 return IRQ_NONE; 288 276 289 - for_each_set_bit(ch, &intst, RZG2L_ADC_MAX_CHANNELS) 277 + for_each_set_bit(ch, &intst, hw_params->num_channels) 290 278 adc->last_val[ch] = rzg2l_adc_readl(adc, RZG2L_ADCR(ch)) & RZG2L_ADCR_AD_MASK; 291 279 292 280 /* clear the channel interrupt */ ··· 299 287 300 288 static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc) 301 289 { 290 + const struct rzg2l_adc_hw_params *hw_params = adc->hw_params; 302 291 struct iio_chan_spec *chan_array; 303 292 struct rzg2l_adc_data *data; 304 293 unsigned int channel; ··· 315 302 if (!num_channels) 316 303 return dev_err_probe(&pdev->dev, -ENODEV, "no channel children\n"); 317 304 318 - if (num_channels > RZG2L_ADC_MAX_CHANNELS) 305 + if (num_channels > hw_params->num_channels) 319 306 return dev_err_probe(&pdev->dev, -EINVAL, 320 307 "num of channel children out of range\n"); 321 308 ··· 330 317 if (ret) 331 318 return ret; 332 319 333 - if (channel >= RZG2L_ADC_MAX_CHANNELS) 320 + if (channel >= hw_params->num_channels) 334 321 return -EINVAL; 335 322 336 323 chan_array[i].type = IIO_VOLTAGE; ··· 350 337 351 338 static int rzg2l_adc_hw_init(struct device *dev, struct rzg2l_adc *adc) 352 339 { 340 + const struct rzg2l_adc_hw_params *hw_params = adc->hw_params; 353 341 u32 reg; 354 342 int ret; 355 343 ··· 368 354 if (ret) 369 355 goto exit_hw_init; 370 356 371 - /* Only division by 4 can be set */ 372 - reg = rzg2l_adc_readl(adc, RZG2L_ADIVC); 373 - reg &= ~RZG2L_ADIVC_DIVADC_MASK; 374 - reg |= RZG2L_ADIVC_DIVADC_4; 375 - rzg2l_adc_writel(adc, RZG2L_ADIVC, reg); 357 + if (hw_params->adivc) { 358 + /* Only division by 4 can be set */ 359 + reg = rzg2l_adc_readl(adc, RZG2L_ADIVC); 360 + reg &= ~RZG2L_ADIVC_DIVADC_MASK; 361 + reg |= RZG2L_ADIVC_DIVADC_4; 362 + rzg2l_adc_writel(adc, RZG2L_ADIVC, reg); 363 + } 376 364 377 365 /* 378 366 * Setup AMD3 ··· 385 369 reg = rzg2l_adc_readl(adc, RZG2L_ADM(3)); 386 370 reg &= ~RZG2L_ADM3_ADIL_MASK; 387 371 reg &= ~RZG2L_ADM3_ADCMP_MASK; 388 - reg &= ~RZG2L_ADM3_ADSMP_MASK; 389 - reg |= (RZG2L_ADM3_ADCMP_E | RZG2L_ADSMP_DEFAULT_SAMPLING); 372 + reg &= ~hw_params->adsmp_mask; 373 + reg |= FIELD_PREP(RZG2L_ADM3_ADCMP_MASK, hw_params->default_adcmp) | 374 + hw_params->default_adsmp; 375 + 390 376 rzg2l_adc_writel(adc, RZG2L_ADM(3), reg); 391 377 392 378 exit_hw_init: ··· 410 392 return -ENOMEM; 411 393 412 394 adc = iio_priv(indio_dev); 395 + 396 + adc->hw_params = device_get_match_data(dev); 397 + if (!adc->hw_params || adc->hw_params->num_channels > RZG2L_ADC_MAX_CHANNELS) 398 + return -EINVAL; 413 399 414 400 ret = rzg2l_adc_parse_properties(pdev, adc); 415 401 if (ret) ··· 468 446 return devm_iio_device_register(dev, indio_dev); 469 447 } 470 448 449 + static const struct rzg2l_adc_hw_params rzg2l_hw_params = { 450 + .num_channels = 8, 451 + .default_adcmp = 0xe, 452 + .default_adsmp = 0x578, 453 + .adsmp_mask = GENMASK(15, 0), 454 + .adint_inten_mask = GENMASK(7, 0), 455 + .adivc = true 456 + }; 457 + 471 458 static const struct of_device_id rzg2l_adc_match[] = { 472 - { .compatible = "renesas,rzg2l-adc",}, 459 + { .compatible = "renesas,rzg2l-adc", .data = &rzg2l_hw_params }, 473 460 { /* sentinel */ } 474 461 }; 475 462 MODULE_DEVICE_TABLE(of, rzg2l_adc_match);