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

hwmon: (ads2828) Convert to use regmap

Simplify code and reduce code size by using regmap to access i2c registers.

Reviewed-and-Tested-by: Robert Rosengren <robert.rosengren@axis.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

+27 -44
+1
drivers/hwmon/Kconfig
··· 1389 1389 config SENSORS_ADS7828 1390 1390 tristate "Texas Instruments ADS7828 and compatibles" 1391 1391 depends on I2C 1392 + select REGMAP_I2C 1392 1393 help 1393 1394 If you say yes here you get support for Texas Instruments ADS7828 and 1394 1395 ADS7830 8-channel A/D converters. ADS7828 resolution is 12-bit, while
+26 -44
drivers/hwmon/ads7828.c
··· 30 30 #include <linux/hwmon-sysfs.h> 31 31 #include <linux/i2c.h> 32 32 #include <linux/init.h> 33 - #include <linux/jiffies.h> 34 33 #include <linux/module.h> 35 - #include <linux/mutex.h> 36 34 #include <linux/platform_data/ads7828.h> 35 + #include <linux/regmap.h> 37 36 #include <linux/slab.h> 38 37 39 38 /* The ADS7828 registers */ 40 - #define ADS7828_NCH 8 /* 8 channels supported */ 41 39 #define ADS7828_CMD_SD_SE 0x80 /* Single ended inputs */ 42 40 #define ADS7828_CMD_PD1 0x04 /* Internal vref OFF && A/D ON */ 43 41 #define ADS7828_CMD_PD3 0x0C /* Internal vref ON && A/D ON */ ··· 48 50 49 51 /* Client specific data */ 50 52 struct ads7828_data { 51 - struct i2c_client *client; 52 - struct mutex update_lock; /* Mutex protecting updates */ 53 - unsigned long last_updated; /* Last updated time (in jiffies) */ 54 - u16 adc_input[ADS7828_NCH]; /* ADS7828_NCH samples */ 55 - bool valid; /* Validity flag */ 53 + struct regmap *regmap; 56 54 bool diff_input; /* Differential input */ 57 55 bool ext_vref; /* External voltage reference */ 58 56 unsigned int vref_mv; /* voltage reference value */ 59 57 u8 cmd_byte; /* Command byte without channel bits */ 60 58 unsigned int lsb_resol; /* Resolution of the ADC sample LSB */ 61 - s32 (*read_channel)(const struct i2c_client *client, u8 command); 62 59 }; 63 60 64 61 /* Command byte C2,C1,C0 - see datasheet */ ··· 62 69 return cmd | (((ch >> 1) | (ch & 0x01) << 2) << 4); 63 70 } 64 71 65 - /* Update data for the device (all 8 channels) */ 66 - static struct ads7828_data *ads7828_update_device(struct device *dev) 67 - { 68 - struct ads7828_data *data = dev_get_drvdata(dev); 69 - struct i2c_client *client = data->client; 70 - 71 - mutex_lock(&data->update_lock); 72 - 73 - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 74 - || !data->valid) { 75 - unsigned int ch; 76 - dev_dbg(&client->dev, "Starting ads7828 update\n"); 77 - 78 - for (ch = 0; ch < ADS7828_NCH; ch++) { 79 - u8 cmd = ads7828_cmd_byte(data->cmd_byte, ch); 80 - data->adc_input[ch] = data->read_channel(client, cmd); 81 - } 82 - data->last_updated = jiffies; 83 - data->valid = true; 84 - } 85 - 86 - mutex_unlock(&data->update_lock); 87 - 88 - return data; 89 - } 90 - 91 72 /* sysfs callback function */ 92 73 static ssize_t ads7828_show_in(struct device *dev, struct device_attribute *da, 93 74 char *buf) 94 75 { 95 76 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 96 - struct ads7828_data *data = ads7828_update_device(dev); 97 - unsigned int value = DIV_ROUND_CLOSEST(data->adc_input[attr->index] * 98 - data->lsb_resol, 1000); 77 + struct ads7828_data *data = dev_get_drvdata(dev); 78 + u8 cmd = ads7828_cmd_byte(data->cmd_byte, attr->index); 79 + unsigned int regval; 80 + int err; 99 81 100 - return sprintf(buf, "%d\n", value); 82 + err = regmap_read(data->regmap, cmd, &regval); 83 + if (err < 0) 84 + return err; 85 + 86 + return sprintf(buf, "%d\n", 87 + DIV_ROUND_CLOSEST(regval * data->lsb_resol, 1000)); 101 88 } 102 89 103 90 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ads7828_show_in, NULL, 0); ··· 102 129 }; 103 130 104 131 ATTRIBUTE_GROUPS(ads7828); 132 + 133 + static const struct regmap_config ads2828_regmap_config = { 134 + .reg_bits = 8, 135 + .val_bits = 16, 136 + }; 137 + 138 + static const struct regmap_config ads2830_regmap_config = { 139 + .reg_bits = 8, 140 + .val_bits = 8, 141 + }; 105 142 106 143 static int ads7828_probe(struct i2c_client *client, 107 144 const struct i2c_device_id *id) ··· 143 160 /* ADS7828 uses 12-bit samples, while ADS7830 is 8-bit */ 144 161 if (id->driver_data == ads7828) { 145 162 data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 4096); 146 - data->read_channel = i2c_smbus_read_word_swapped; 163 + data->regmap = devm_regmap_init_i2c(client, 164 + &ads2828_regmap_config); 147 165 } else { 148 166 data->lsb_resol = DIV_ROUND_CLOSEST(data->vref_mv * 1000, 256); 149 - data->read_channel = i2c_smbus_read_byte_data; 167 + data->regmap = devm_regmap_init_i2c(client, 168 + &ads2830_regmap_config); 150 169 } 151 170 152 171 data->cmd_byte = data->ext_vref ? ADS7828_CMD_PD1 : ADS7828_CMD_PD3; 153 172 if (!data->diff_input) 154 173 data->cmd_byte |= ADS7828_CMD_SD_SE; 155 - 156 - data->client = client; 157 - mutex_init(&data->update_lock); 158 174 159 175 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 160 176 data,