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: al3320a: 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-5-d189bea87261@ixit.cz
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

David Heidelberg and committed by
Jonathan Cameron
1850e6ae 0e5e21e2

+51 -42
+51 -42
drivers/iio/light/al3320a.c
··· 15 15 #include <linux/bitfield.h> 16 16 #include <linux/i2c.h> 17 17 #include <linux/module.h> 18 + #include <linux/regmap.h> 18 19 #include <linux/mod_devicetable.h> 19 20 20 21 #include <linux/iio/iio.h> ··· 58 57 {0, 512000}, {0, 128000}, {0, 32000}, {0, 10000} 59 58 }; 60 59 60 + static const struct regmap_config al3320a_regmap_config = { 61 + .reg_bits = 8, 62 + .val_bits = 8, 63 + .max_register = AL3320A_REG_HIGH_THRESH_HIGH, 64 + }; 65 + 61 66 struct al3320a_data { 62 - struct i2c_client *client; 67 + struct regmap *regmap; 63 68 }; 64 69 65 70 static const struct iio_chan_spec al3320a_channels[] = { ··· 87 80 .attrs = al3320a_attributes, 88 81 }; 89 82 90 - static int al3320a_set_pwr_on(struct i2c_client *client) 83 + static int al3320a_set_pwr_on(struct al3320a_data *data) 91 84 { 92 - return i2c_smbus_write_byte_data(client, AL3320A_REG_CONFIG, AL3320A_CONFIG_ENABLE); 85 + return regmap_write(data->regmap, AL3320A_REG_CONFIG, AL3320A_CONFIG_ENABLE); 93 86 } 94 87 95 88 static void al3320a_set_pwr_off(void *_data) 96 89 { 97 90 struct al3320a_data *data = _data; 91 + struct device *dev = regmap_get_device(data->regmap); 92 + int ret; 98 93 99 - i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG, AL3320A_CONFIG_DISABLE); 94 + ret = regmap_write(data->regmap, AL3320A_REG_CONFIG, AL3320A_CONFIG_DISABLE); 95 + if (ret) 96 + dev_err(dev, "failed to write system register\n"); 100 97 } 101 98 102 99 static int al3320a_init(struct al3320a_data *data) 103 100 { 101 + struct device *dev = regmap_get_device(data->regmap); 104 102 int ret; 105 103 106 - ret = al3320a_set_pwr_on(data->client); 107 - 108 - if (ret < 0) 109 - return ret; 110 - 111 - ret = devm_add_action_or_reset(&data->client->dev, 112 - al3320a_set_pwr_off, 113 - data); 104 + ret = al3320a_set_pwr_on(data); 114 105 if (ret) 115 106 return ret; 116 107 117 - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_CONFIG_RANGE, 118 - FIELD_PREP(AL3320A_GAIN_MASK, 119 - AL3320A_RANGE_3)); 120 - if (ret < 0) 108 + ret = devm_add_action_or_reset(dev, al3320a_set_pwr_off, data); 109 + if (ret) 121 110 return ret; 122 111 123 - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_MEAN_TIME, 124 - AL3320A_DEFAULT_MEAN_TIME); 125 - if (ret < 0) 112 + ret = regmap_write(data->regmap, AL3320A_REG_CONFIG_RANGE, 113 + FIELD_PREP(AL3320A_GAIN_MASK, AL3320A_RANGE_3)); 114 + if (ret) 126 115 return ret; 127 116 128 - ret = i2c_smbus_write_byte_data(data->client, AL3320A_REG_WAIT, 129 - AL3320A_DEFAULT_WAIT_TIME); 130 - if (ret < 0) 117 + ret = regmap_write(data->regmap, AL3320A_REG_MEAN_TIME, 118 + AL3320A_DEFAULT_MEAN_TIME); 119 + if (ret) 131 120 return ret; 132 121 133 - return 0; 122 + return regmap_write(data->regmap, AL3320A_REG_WAIT, 123 + AL3320A_DEFAULT_WAIT_TIME); 134 124 } 135 125 136 126 static int al3320a_read_raw(struct iio_dev *indio_dev, ··· 135 131 int *val2, long mask) 136 132 { 137 133 struct al3320a_data *data = iio_priv(indio_dev); 138 - int ret; 134 + int ret, gain, raw; 139 135 140 136 switch (mask) { 141 137 case IIO_CHAN_INFO_RAW: ··· 144 140 * - low byte of output is stored at AL3320A_REG_DATA_LOW 145 141 * - high byte of output is stored at AL3320A_REG_DATA_LOW + 1 146 142 */ 147 - ret = i2c_smbus_read_word_data(data->client, 148 - AL3320A_REG_DATA_LOW); 149 - if (ret < 0) 150 - return ret; 151 - *val = ret; 152 - return IIO_VAL_INT; 153 - case IIO_CHAN_INFO_SCALE: 154 - ret = i2c_smbus_read_byte_data(data->client, 155 - AL3320A_REG_CONFIG_RANGE); 156 - if (ret < 0) 143 + ret = regmap_read(data->regmap, AL3320A_REG_DATA_LOW, &raw); 144 + if (ret) 157 145 return ret; 158 146 159 - ret = FIELD_GET(AL3320A_GAIN_MASK, ret); 160 - *val = al3320a_scales[ret][0]; 161 - *val2 = al3320a_scales[ret][1]; 147 + *val = raw; 148 + 149 + return IIO_VAL_INT; 150 + case IIO_CHAN_INFO_SCALE: 151 + ret = regmap_read(data->regmap, AL3320A_REG_CONFIG_RANGE, &gain); 152 + if (ret) 153 + return ret; 154 + 155 + gain = FIELD_GET(AL3320A_GAIN_MASK, gain); 156 + *val = al3320a_scales[gain][0]; 157 + *val2 = al3320a_scales[gain][1]; 162 158 163 159 return IIO_VAL_INT_PLUS_MICRO; 164 160 } ··· 179 175 val2 != al3320a_scales[i][1]) 180 176 continue; 181 177 182 - return i2c_smbus_write_byte_data(data->client, 183 - AL3320A_REG_CONFIG_RANGE, 184 - FIELD_PREP(AL3320A_GAIN_MASK, i)); 178 + return regmap_write(data->regmap, AL3320A_REG_CONFIG_RANGE, 179 + FIELD_PREP(AL3320A_GAIN_MASK, i)); 185 180 } 186 181 break; 187 182 } ··· 206 203 207 204 data = iio_priv(indio_dev); 208 205 i2c_set_clientdata(client, indio_dev); 209 - data->client = client; 206 + 207 + data->regmap = devm_regmap_init_i2c(client, &al3320a_regmap_config); 208 + if (IS_ERR(data->regmap)) 209 + return dev_err_probe(dev, PTR_ERR(data->regmap), 210 + "cannot allocate regmap\n"); 210 211 211 212 indio_dev->info = &al3320a_info; 212 213 indio_dev->name = "al3320a"; ··· 237 230 238 231 static int al3320a_resume(struct device *dev) 239 232 { 240 - return al3320a_set_pwr_on(to_i2c_client(dev)); 233 + struct al3320a_data *data = iio_priv(dev_get_drvdata(dev)); 234 + 235 + return al3320a_set_pwr_on(data); 241 236 } 242 237 243 238 static DEFINE_SIMPLE_DEV_PM_OPS(al3320a_pm_ops, al3320a_suspend,