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

iio: adc: ad7091r: Move chip init data to container struct

AD7091R designs may differ on their communication protocol and resources
required for proper setup. Extract what is design specific into a
init_info struct so the base driver can use data and callback functions
from that struct rather than checking which specific chip is connected
during device initialization.

Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
Link: https://lore.kernel.org/r/1aca2261e227474dc58ce26442845947bcde9b14.1703013352.git.marcelo.schmitt1@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Marcelo Schmitt and committed by
Jonathan Cameron
ca1a6790 5b035ed0

+55 -30
+12 -15
drivers/iio/adc/ad7091r-base.c
··· 342 342 } 343 343 344 344 int ad7091r_probe(struct device *dev, const char *name, 345 - const struct ad7091r_chip_info *chip_info, 345 + const struct ad7091r_init_info *init_info, 346 346 struct regmap *map, int irq) 347 347 { 348 348 struct iio_dev *iio_dev; ··· 355 355 356 356 st = iio_priv(iio_dev); 357 357 st->dev = dev; 358 - st->chip_info = chip_info; 359 - st->map = map; 358 + init_info->init_adc_regmap(st, init_info->regmap_config); 359 + if (IS_ERR(st->map)) 360 + return dev_err_probe(st->dev, PTR_ERR(st->map), 361 + "Error initializing regmap\n"); 360 362 361 - iio_dev->name = name; 362 363 iio_dev->info = &ad7091r_info; 363 364 iio_dev->modes = INDIO_DIRECT_MODE; 364 365 365 - iio_dev->num_channels = chip_info->num_channels; 366 - iio_dev->channels = chip_info->channels; 367 - 368 366 if (irq) { 367 + st->chip_info = init_info->info_irq; 369 368 ret = regmap_update_bits(st->map, AD7091R_REG_CONF, 370 369 AD7091R_REG_CONF_ALERT_EN, BIT(4)); 371 370 if (ret) ··· 376 377 IRQF_ONESHOT, name, iio_dev); 377 378 if (ret) 378 379 return ret; 380 + } else { 381 + st->chip_info = init_info->info_no_irq; 379 382 } 383 + 384 + iio_dev->name = st->chip_info->name; 385 + iio_dev->num_channels = st->chip_info->num_channels; 386 + iio_dev->channels = st->chip_info->channels; 380 387 381 388 st->vref = devm_regulator_get_optional(dev, "vref"); 382 389 if (IS_ERR(st->vref)) { ··· 437 432 } 438 433 } 439 434 EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, IIO_AD7091R); 440 - 441 - const struct regmap_config ad7091r_regmap_config = { 442 - .reg_bits = 8, 443 - .val_bits = 16, 444 - .writeable_reg = ad7091r_writeable_reg, 445 - .volatile_reg = ad7091r_volatile_reg, 446 - }; 447 - EXPORT_SYMBOL_NS_GPL(ad7091r_regmap_config, IIO_AD7091R); 448 435 449 436 MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>"); 450 437 MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters");
+12 -3
drivers/iio/adc/ad7091r-base.h
··· 8 8 #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__ 9 9 #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__ 10 10 11 + #include <linux/regmap.h> 12 + 11 13 #define AD7091R_REG_RESULT 0 12 14 #define AD7091R_REG_CHANNEL 1 13 15 #define AD7091R_REG_CONF 2 ··· 54 52 }; 55 53 56 54 struct ad7091r_chip_info { 55 + const char *name; 57 56 unsigned int num_channels; 58 57 const struct iio_chan_spec *channels; 59 58 unsigned int vref_mV; 60 59 }; 61 60 61 + struct ad7091r_init_info { 62 + const struct ad7091r_chip_info *info_irq; 63 + const struct ad7091r_chip_info *info_no_irq; 64 + const struct regmap_config *regmap_config; 65 + void (*init_adc_regmap)(struct ad7091r_state *st, 66 + const struct regmap_config *regmap_conf); 67 + }; 68 + 62 69 extern const struct iio_event_spec ad7091r_events[3]; 63 70 64 - extern const struct regmap_config ad7091r_regmap_config; 65 - 66 71 int ad7091r_probe(struct device *dev, const char *name, 67 - const struct ad7091r_chip_info *chip_info, 72 + const struct ad7091r_init_info *init_info, 68 73 struct regmap *map, int irq); 69 74 70 75 bool ad7091r_volatile_reg(struct device *dev, unsigned int reg);
+31 -12
drivers/iio/adc/ad7091r5.c
··· 27 27 }; 28 28 29 29 static const struct ad7091r_chip_info ad7091r5_chip_info_irq = { 30 + .name = "ad7091r-5", 30 31 .channels = ad7091r5_channels_irq, 31 32 .num_channels = ARRAY_SIZE(ad7091r5_channels_irq), 32 33 .vref_mV = 2500, 33 34 }; 34 35 35 36 static const struct ad7091r_chip_info ad7091r5_chip_info_noirq = { 37 + .name = "ad7091r-5", 36 38 .channels = ad7091r5_channels_noirq, 37 39 .num_channels = ARRAY_SIZE(ad7091r5_channels_noirq), 38 40 .vref_mV = 2500, 39 41 }; 40 42 43 + static const struct regmap_config ad7091r_regmap_config = { 44 + .reg_bits = 8, 45 + .val_bits = 16, 46 + .writeable_reg = ad7091r_writeable_reg, 47 + .volatile_reg = ad7091r_volatile_reg, 48 + }; 49 + 50 + static void ad7091r5_regmap_init(struct ad7091r_state *st, 51 + const struct regmap_config *regmap_conf) 52 + { 53 + struct i2c_client *i2c = container_of(st->dev, struct i2c_client, dev); 54 + 55 + st->map = devm_regmap_init_i2c(i2c, regmap_conf); 56 + } 57 + 58 + static struct ad7091r_init_info ad7091r5_init_info = { 59 + .info_irq = &ad7091r5_chip_info_irq, 60 + .info_no_irq = &ad7091r5_chip_info_noirq, 61 + .regmap_config = &ad7091r_regmap_config, 62 + .init_adc_regmap = &ad7091r5_regmap_init 63 + }; 64 + 41 65 static int ad7091r5_i2c_probe(struct i2c_client *i2c) 42 66 { 43 67 const struct i2c_device_id *id = i2c_client_get_device_id(i2c); 44 - const struct ad7091r_chip_info *chip_info; 45 - struct regmap *map = devm_regmap_init_i2c(i2c, &ad7091r_regmap_config); 68 + const struct ad7091r_init_info *init_info; 46 69 47 - if (IS_ERR(map)) 48 - return PTR_ERR(map); 70 + init_info = i2c_get_match_data(i2c); 71 + if (!init_info) 72 + return -EINVAL; 49 73 50 - if (i2c->irq) 51 - chip_info = &ad7091r5_chip_info_irq; 52 - else 53 - chip_info = &ad7091r5_chip_info_noirq; 54 - 55 - return ad7091r_probe(&i2c->dev, id->name, chip_info, map, i2c->irq); 74 + return ad7091r_probe(&i2c->dev, id->name, init_info, NULL, i2c->irq); 56 75 } 57 76 58 77 static const struct of_device_id ad7091r5_dt_ids[] = { 59 - { .compatible = "adi,ad7091r5" }, 78 + { .compatible = "adi,ad7091r5", .data = &ad7091r5_init_info }, 60 79 {}, 61 80 }; 62 81 MODULE_DEVICE_TABLE(of, ad7091r5_dt_ids); 63 82 64 83 static const struct i2c_device_id ad7091r5_i2c_ids[] = { 65 - {"ad7091r5", 0}, 84 + {"ad7091r5", (kernel_ulong_t)&ad7091r5_init_info }, 66 85 {} 67 86 }; 68 87 MODULE_DEVICE_TABLE(i2c, ad7091r5_i2c_ids);