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: light: al3010: Implement regmap support

Modernize and clean up the driver using the regmap framework.

With the regmap implementation, the compiler produces
a significantly smaller module.

Size before: 72 kB
Size after: 58 kB

Signed-off-by: David Heidelberg <david@ixit.cz>
Link: https://patch.msgid.link/20250402-al3010-iio-regmap-v4-4-d189bea87261@ixit.cz
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Heidelberg and committed by
Jonathan Cameron
0e5e21e2 b8154f34

+44 -38
+44 -38
drivers/iio/light/al3010.c
··· 17 17 #include <linux/bitfield.h> 18 18 #include <linux/i2c.h> 19 19 #include <linux/module.h> 20 + #include <linux/regmap.h> 20 21 #include <linux/mod_devicetable.h> 21 22 22 23 #include <linux/iio/iio.h> ··· 45 44 {0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600} 46 45 }; 47 46 47 + static const struct regmap_config al3010_regmap_config = { 48 + .reg_bits = 8, 49 + .val_bits = 8, 50 + .max_register = AL3010_REG_CONFIG, 51 + }; 52 + 48 53 struct al3010_data { 49 - struct i2c_client *client; 54 + struct regmap *regmap; 50 55 }; 51 56 52 57 static const struct iio_chan_spec al3010_channels[] = { ··· 74 67 .attrs = al3010_attributes, 75 68 }; 76 69 77 - static int al3010_set_pwr_on(struct i2c_client *client) 70 + static int al3010_set_pwr_on(struct al3010_data *data) 78 71 { 79 - return i2c_smbus_write_byte_data(client, AL3010_REG_SYSTEM, 80 - AL3010_CONFIG_ENABLE); 72 + return regmap_write(data->regmap, AL3010_REG_SYSTEM, AL3010_CONFIG_ENABLE); 81 73 } 82 74 83 75 static void al3010_set_pwr_off(void *_data) 84 76 { 85 77 struct al3010_data *data = _data; 78 + struct device *dev = regmap_get_device(data->regmap); 79 + int ret; 86 80 87 - i2c_smbus_write_byte_data(data->client, AL3010_REG_SYSTEM, 88 - AL3010_CONFIG_DISABLE); 81 + ret = regmap_write(data->regmap, AL3010_REG_SYSTEM, AL3010_CONFIG_DISABLE); 82 + if (ret) 83 + dev_err(dev, "failed to write system register\n"); 89 84 } 90 85 91 86 static int al3010_init(struct al3010_data *data) 92 87 { 88 + struct device *dev = regmap_get_device(data->regmap); 93 89 int ret; 94 90 95 - ret = al3010_set_pwr_on(data->client); 96 - if (ret < 0) 97 - return ret; 98 - 99 - ret = devm_add_action_or_reset(&data->client->dev, 100 - al3010_set_pwr_off, 101 - data); 91 + ret = al3010_set_pwr_on(data); 102 92 if (ret) 103 93 return ret; 104 94 105 - ret = i2c_smbus_write_byte_data(data->client, AL3010_REG_CONFIG, 106 - FIELD_PREP(AL3010_GAIN_MASK, 107 - AL3XXX_RANGE_3)); 108 - if (ret < 0) 95 + ret = devm_add_action_or_reset(dev, al3010_set_pwr_off, data); 96 + if (ret) 109 97 return ret; 110 - 111 - return 0; 98 + return regmap_write(data->regmap, AL3010_REG_CONFIG, 99 + FIELD_PREP(AL3010_GAIN_MASK, AL3XXX_RANGE_3)); 112 100 } 113 101 114 102 static int al3010_read_raw(struct iio_dev *indio_dev, ··· 111 109 int *val2, long mask) 112 110 { 113 111 struct al3010_data *data = iio_priv(indio_dev); 114 - int ret; 112 + int ret, gain, raw; 115 113 116 114 switch (mask) { 117 115 case IIO_CHAN_INFO_RAW: ··· 120 118 * - low byte of output is stored at AL3010_REG_DATA_LOW 121 119 * - high byte of output is stored at AL3010_REG_DATA_LOW + 1 122 120 */ 123 - ret = i2c_smbus_read_word_data(data->client, 124 - AL3010_REG_DATA_LOW); 125 - if (ret < 0) 126 - return ret; 127 - *val = ret; 128 - return IIO_VAL_INT; 129 - case IIO_CHAN_INFO_SCALE: 130 - ret = i2c_smbus_read_byte_data(data->client, 131 - AL3010_REG_CONFIG); 132 - if (ret < 0) 121 + ret = regmap_read(data->regmap, AL3010_REG_DATA_LOW, &raw); 122 + if (ret) 133 123 return ret; 134 124 135 - ret = FIELD_GET(AL3010_GAIN_MASK, ret); 136 - *val = al3010_scales[ret][0]; 137 - *val2 = al3010_scales[ret][1]; 125 + *val = raw; 126 + 127 + return IIO_VAL_INT; 128 + case IIO_CHAN_INFO_SCALE: 129 + ret = regmap_read(data->regmap, AL3010_REG_CONFIG, &gain); 130 + if (ret) 131 + return ret; 132 + 133 + gain = FIELD_GET(AL3010_GAIN_MASK, gain); 134 + *val = al3010_scales[gain][0]; 135 + *val2 = al3010_scales[gain][1]; 138 136 139 137 return IIO_VAL_INT_PLUS_MICRO; 140 138 } ··· 155 153 val2 != al3010_scales[i][1]) 156 154 continue; 157 155 158 - return i2c_smbus_write_byte_data(data->client, 159 - AL3010_REG_CONFIG, 160 - FIELD_PREP(AL3010_GAIN_MASK, i)); 156 + return regmap_write(data->regmap, AL3010_REG_CONFIG, 157 + FIELD_PREP(AL3010_GAIN_MASK, i)); 161 158 } 162 159 break; 163 160 } ··· 182 181 183 182 data = iio_priv(indio_dev); 184 183 i2c_set_clientdata(client, indio_dev); 185 - data->client = client; 184 + data->regmap = devm_regmap_init_i2c(client, &al3010_regmap_config); 185 + if (IS_ERR(data->regmap)) 186 + return dev_err_probe(dev, PTR_ERR(data->regmap), 187 + "cannot allocate regmap\n"); 186 188 187 189 indio_dev->info = &al3010_info; 188 190 indio_dev->name = "al3010"; ··· 210 206 211 207 static int al3010_resume(struct device *dev) 212 208 { 213 - return al3010_set_pwr_on(to_i2c_client(dev)); 209 + struct al3010_data *data = iio_priv(dev_get_drvdata(dev)); 210 + 211 + return al3010_set_pwr_on(data); 214 212 } 215 213 216 214 static DEFINE_SIMPLE_DEV_PM_OPS(al3010_pm_ops, al3010_suspend, al3010_resume);