On Tue, 18 Jun 2019 11:06:33 +0200 Fabien Lahoudere <fabien.lahoudere@xxxxxxxxxxxxx> wrote: > To avoid code duplication, we move channels initialization in > cros_ec_sensors_core. > > Signed-off-by: Fabien Lahoudere <fabien.lahoudere@xxxxxxxxxxxxx> Hi Fabien, In of itself a fairly minor gain in code sharing and at some slight cost in readability. Still on balance worthwhile I think. Minor stuff inline. Thanks, Jonathan > --- > .../common/cros_ec_sensors/cros_ec_sensors.c | 49 ++++++------------- > .../cros_ec_sensors/cros_ec_sensors_core.c | 25 +++++++++- > drivers/iio/light/cros_ec_light_prox.c | 42 ++++------------ > drivers/iio/pressure/cros_ec_baro.c | 38 +++----------- > .../linux/iio/common/cros_ec_sensors_core.h | 24 ++++++++- > 5 files changed, 78 insertions(+), 100 deletions(-) > > diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c > index c59b0ab8fe7d..897dc83a3355 100644 > --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c > +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c > @@ -28,8 +28,6 @@ > struct cros_ec_sensors_state { > /* Shared by all sensors */ > struct cros_ec_sensors_core_state core; > - > - struct iio_chan_spec channels[CROS_EC_SENSORS_MAX_CHANNELS]; > }; > > static int cros_ec_sensors_read(struct iio_dev *indio_dev, > @@ -178,7 +176,6 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) > struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); > struct iio_dev *indio_dev; > struct cros_ec_sensors_state *state; > - struct iio_chan_spec *channel; > int ret, i; > > if (!ec_dev || !ec_dev->ec_dev) { > @@ -186,63 +183,49 @@ static int cros_ec_sensors_probe(struct platform_device *pdev) > return -EINVAL; > } > > - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*state)); > - if (!indio_dev) > - return -ENOMEM; > - > - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); > + ret = cros_ec_sensors_core_init(pdev, sizeof(*state), > + CROS_EC_SENSORS_MAX_CHANNELS, true); > if (ret) > return ret; > > + indio_dev = platform_get_drvdata(pdev); > state = iio_priv(indio_dev); > - for (channel = state->channels, i = CROS_EC_SENSOR_X; > - i < CROS_EC_SENSOR_MAX_AXIS; i++, channel++) { > + for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) { > /* Common part */ > - channel->info_mask_separate = > + cros_ec_core_channel_init(state->core.channels, i + 1); Given this is kind of 'partially' initializing the channel, perhaps we can name it as something that hints at that. cros_ec_core_channel_common_init() or something like that? > + state->core.channels[i + 1].info_mask_separate = > BIT(IIO_CHAN_INFO_RAW) | > BIT(IIO_CHAN_INFO_CALIBBIAS); > - channel->info_mask_shared_by_all = > + state->core.channels[i + 1].info_mask_shared_by_all = > BIT(IIO_CHAN_INFO_SCALE) | > BIT(IIO_CHAN_INFO_FREQUENCY) | > BIT(IIO_CHAN_INFO_SAMP_FREQ); > - channel->scan_type.realbits = CROS_EC_SENSOR_BITS; > - channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; > - channel->scan_index = i; > - channel->ext_info = cros_ec_sensors_ext_info; > - channel->modified = 1; > - channel->channel2 = IIO_MOD_X + i; > - channel->scan_type.sign = 's'; > + state->core.channels[i + 1].scan_index = i; > + state->core.channels[i + 1].modified = 1; > + state->core.channels[i + 1].channel2 = IIO_MOD_X + i; > + state->core.channels[i + 1].scan_type.sign = 's'; > > /* Sensor specific */ > switch (state->core.type) { > case MOTIONSENSE_TYPE_ACCEL: > - channel->type = IIO_ACCEL; > + state->core.channels[i + 1].type = IIO_ACCEL; > break; > case MOTIONSENSE_TYPE_GYRO: > - channel->type = IIO_ANGL_VEL; > + state->core.channels[i + 1].type = IIO_ANGL_VEL; > break; > case MOTIONSENSE_TYPE_MAG: > - channel->type = IIO_MAGN; > + state->core.channels[i + 1].type = IIO_MAGN; > break; > default: > dev_err(&pdev->dev, "Unknown motion sensor\n"); > return -EINVAL; > } > } > + state->core.channels[0].scan_index = CROS_EC_SENSOR_MAX_AXIS; > + > state->core.info.read_raw = &cros_ec_sensors_read; > state->core.info.write_raw = &cros_ec_sensors_write; > > - /* Timestamp */ > - channel->type = IIO_TIMESTAMP; > - channel->channel = -1; > - channel->scan_index = CROS_EC_SENSOR_MAX_AXIS; > - channel->scan_type.sign = 's'; > - channel->scan_type.realbits = 64; > - channel->scan_type.storagebits = 64; > - > - indio_dev->channels = state->channels; > - indio_dev->num_channels = CROS_EC_SENSORS_MAX_CHANNELS; > - > /* There is only enough room for accel and gyro in the io space */ > if ((state->core.ec->cmd_readmem != NULL) && > (state->core.type != MOTIONSENSE_TYPE_MAG)) > diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c > index a1b324e1a5d8..e5181e007dd7 100644 > --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c > +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c > @@ -26,15 +26,25 @@ static char *cros_ec_loc[] = { > }; > > int cros_ec_sensors_core_init(struct platform_device *pdev, > - struct iio_dev *indio_dev, > + int sizeof_priv, > + int num_channels, > bool physical_device) > { > struct device *dev = &pdev->dev; > - struct cros_ec_sensors_core_state *state = iio_priv(indio_dev); > + struct cros_ec_sensors_core_state *state; > struct cros_ec_dev *ec = dev_get_drvdata(pdev->dev.parent); > struct cros_ec_sensor_platform *sensor_platform = dev_get_platdata(dev); > + struct iio_dev *indio_dev; > + > + if (num_channels > CROS_EC_SENSORS_CORE_MAX_CHANNELS) > + return -EINVAL; > + > + indio_dev = devm_iio_device_alloc(dev, sizeof_priv); > + if (!indio_dev) > + return -ENOMEM; > > platform_set_drvdata(pdev, indio_dev); > + state = iio_priv(indio_dev); > > state->ec = ec->ec_dev; > state->msg = devm_kzalloc(&pdev->dev, > @@ -70,6 +80,17 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, > > indio_dev->info = &state->info; > > + /* Timestamp channel */ > + state->channels[0].type = IIO_TIMESTAMP; > + state->channels[0].channel = -1; > + state->channels[0].scan_index = 0; > + state->channels[0].scan_type.sign = 's'; > + state->channels[0].scan_type.realbits = 64; > + state->channels[0].scan_type.storagebits = 64; > + > + indio_dev->channels = state->channels; > + indio_dev->num_channels = num_channels; > + > return 0; > } > EXPORT_SYMBOL_GPL(cros_ec_sensors_core_init); > diff --git a/drivers/iio/light/cros_ec_light_prox.c b/drivers/iio/light/cros_ec_light_prox.c > index b319d95fb70f..32ea5afd495f 100644 > --- a/drivers/iio/light/cros_ec_light_prox.c > +++ b/drivers/iio/light/cros_ec_light_prox.c > @@ -31,8 +31,6 @@ > struct cros_ec_light_prox_state { > /* Shared by all sensors */ > struct cros_ec_sensors_core_state core; > - > - struct iio_chan_spec channels[CROS_EC_LIGHT_PROX_MAX_CHANNELS]; > }; > > static int cros_ec_light_prox_read(struct iio_dev *indio_dev, > @@ -167,7 +165,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) > struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); > struct iio_dev *indio_dev; > struct cros_ec_light_prox_state *state; > - struct iio_chan_spec *channel; > int ret; > > if (!ec_dev || !ec_dev->ec_dev) { > @@ -175,46 +172,38 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) > return -EINVAL; > } > > - indio_dev = devm_iio_device_alloc(dev, sizeof(*state)); > - if (!indio_dev) > - return -ENOMEM; > - > - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); > + ret = cros_ec_sensors_core_init(pdev, sizeof(*state), > + CROS_EC_LIGHT_PROX_MAX_CHANNELS, true); > if (ret) > return ret; > > + indio_dev = platform_get_drvdata(pdev); > state = iio_priv(indio_dev); > state->core.type = state->core.resp->info.type; > state->core.loc = state->core.resp->info.location; > state->core.info.read_raw = &cros_ec_light_prox_read; > state->core.info.write_raw = &cros_ec_light_prox_write; > - channel = state->channels; > > /* Common part */ > - channel->info_mask_shared_by_all = > + cros_ec_core_channel_init(state->core.channels, 1); > + state->core.channels[1].info_mask_shared_by_all = > BIT(IIO_CHAN_INFO_SAMP_FREQ) | > BIT(IIO_CHAN_INFO_FREQUENCY); > - channel->scan_type.realbits = CROS_EC_SENSOR_BITS; > - channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; > - channel->scan_type.shift = 0; > - channel->scan_index = 0; > - channel->ext_info = cros_ec_sensors_ext_info; > - channel->scan_type.sign = 'u'; > > state->core.calib[0] = 0; > > /* Sensor specific */ > switch (state->core.type) { > case MOTIONSENSE_TYPE_LIGHT: > - channel->type = IIO_LIGHT; > - channel->info_mask_separate = > + state->core.channels[1].type = IIO_LIGHT; > + state->core.channels[1].info_mask_separate = > BIT(IIO_CHAN_INFO_PROCESSED) | > BIT(IIO_CHAN_INFO_CALIBBIAS) | > BIT(IIO_CHAN_INFO_CALIBSCALE); > break; > case MOTIONSENSE_TYPE_PROX: > - channel->type = IIO_PROXIMITY; > - channel->info_mask_separate = > + state->core.channels[1].type = IIO_PROXIMITY; > + state->core.channels[1].info_mask_separate = > BIT(IIO_CHAN_INFO_RAW) | > BIT(IIO_CHAN_INFO_CALIBBIAS) | > BIT(IIO_CHAN_INFO_CALIBSCALE); > @@ -224,19 +213,6 @@ static int cros_ec_light_prox_probe(struct platform_device *pdev) > return -EINVAL; > } > > - /* Timestamp */ > - channel++; > - channel->type = IIO_TIMESTAMP; > - channel->channel = -1; > - channel->scan_index = 1; > - channel->scan_type.sign = 's'; > - channel->scan_type.realbits = 64; > - channel->scan_type.storagebits = 64; > - > - indio_dev->channels = state->channels; > - > - indio_dev->num_channels = CROS_EC_LIGHT_PROX_MAX_CHANNELS; > - > state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; > > ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, > diff --git a/drivers/iio/pressure/cros_ec_baro.c b/drivers/iio/pressure/cros_ec_baro.c > index 85a4864e3a4e..8718036d74d2 100644 > --- a/drivers/iio/pressure/cros_ec_baro.c > +++ b/drivers/iio/pressure/cros_ec_baro.c > @@ -29,8 +29,6 @@ > struct cros_ec_baro_state { > /* Shared by all sensors */ > struct cros_ec_sensors_core_state core; > - > - struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS]; > }; > > static int cros_ec_baro_read(struct iio_dev *indio_dev, > @@ -113,7 +111,6 @@ static int cros_ec_baro_probe(struct platform_device *pdev) > struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent); > struct iio_dev *indio_dev; > struct cros_ec_baro_state *state; > - struct iio_chan_spec *channel; > int ret; > > if (!ec_dev || !ec_dev->ec_dev) { > @@ -121,57 +118,38 @@ static int cros_ec_baro_probe(struct platform_device *pdev) > return -EINVAL; > } > > - indio_dev = devm_iio_device_alloc(dev, sizeof(*state)); > - if (!indio_dev) > - return -ENOMEM; > - > - ret = cros_ec_sensors_core_init(pdev, indio_dev, true); > + ret = cros_ec_sensors_core_init(pdev, sizeof(*state), > + CROS_EC_BARO_MAX_CHANNELS, true); > if (ret) > return ret; > > + indio_dev = platform_get_drvdata(pdev); > state = iio_priv(indio_dev); > state->core.type = state->core.resp->info.type; > state->core.loc = state->core.resp->info.location; > state->core.info.read_raw = &cros_ec_baro_read; > state->core.info.write_raw = &cros_ec_baro_write; > - channel = state->channels; > + > /* Common part */ > - channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); > - channel->info_mask_shared_by_all = > + cros_ec_core_channel_init(state->core.channels, 1); > + state->core.channels[1].info_mask_separate = BIT(IIO_CHAN_INFO_RAW); > + state->core.channels[1].info_mask_shared_by_all = > BIT(IIO_CHAN_INFO_SCALE) | > BIT(IIO_CHAN_INFO_SAMP_FREQ) | > BIT(IIO_CHAN_INFO_FREQUENCY); > - channel->scan_type.realbits = CROS_EC_SENSOR_BITS; > - channel->scan_type.storagebits = CROS_EC_SENSOR_BITS; > - channel->scan_type.shift = 0; > - channel->scan_index = 0; > - channel->ext_info = cros_ec_sensors_ext_info; > - channel->scan_type.sign = 'u'; > > state->core.calib[0] = 0; > > /* Sensor specific */ > switch (state->core.type) { > case MOTIONSENSE_TYPE_BARO: > - channel->type = IIO_PRESSURE; > + state->core.channels[1].type = IIO_PRESSURE; > break; > default: > dev_warn(dev, "Unknown motion sensor\n"); > return -EINVAL; > } > > - /* Timestamp */ > - channel++; > - channel->type = IIO_TIMESTAMP; > - channel->channel = -1; > - channel->scan_index = 1; > - channel->scan_type.sign = 's'; > - channel->scan_type.realbits = 64; > - channel->scan_type.storagebits = 64; > - > - indio_dev->channels = state->channels; > - indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS; > - > state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd; > > ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, > diff --git a/include/linux/iio/common/cros_ec_sensors_core.h b/include/linux/iio/common/cros_ec_sensors_core.h > index a729e667f760..485c649b421f 100644 > --- a/include/linux/iio/common/cros_ec_sensors_core.h > +++ b/include/linux/iio/common/cros_ec_sensors_core.h > @@ -31,6 +31,8 @@ enum { > /* Minimum sampling period to use when device is suspending */ > #define CROS_EC_MIN_SUSPEND_SAMPLING_FREQUENCY 1000 /* 1 second */ > > +#define CROS_EC_SENSORS_CORE_MAX_CHANNELS 8 > + > /** > * struct cros_ec_sensors_core_state - state data for EC sensors IIO driver > * @ec: cros EC device structure > @@ -71,6 +73,7 @@ struct cros_ec_sensors_core_state { > > int curr_sampl_freq; > struct iio_info info; > + struct iio_chan_spec channels[CROS_EC_SENSORS_CORE_MAX_CHANNELS]; > }; > > /** > @@ -102,13 +105,15 @@ struct platform_device; > /** > * cros_ec_sensors_core_init() - basic initialization of the core structure > * @pdev: platform device created for the sensors > - * @indio_dev: iio device structure of the device > + * @sizeof_priv: size of the private structure > + * @num_channels: Number of channel > * @physical_device: true if the device refers to a physical device > * > * Return: 0 on success, -errno on failure. > */ > int cros_ec_sensors_core_init(struct platform_device *pdev, > - struct iio_dev *indio_dev, bool physical_device); > + int sizeof_priv, int num_channels, > + bool physical_device); > > /** > * cros_ec_sensors_capture() - the trigger handler function > @@ -124,6 +129,21 @@ int cros_ec_sensors_core_init(struct platform_device *pdev, > */ > irqreturn_t cros_ec_sensors_capture(int irq, void *p); > > +/** > + * cros_ec_core_channel_init() - initialize channel > + * @channel: channels table > + * @idx: channel index to initialize > + * > + * Return: 0 on success, -errno on failure. > + */ > +#define cros_ec_core_channel_init(channel, idx) \ > + channel[idx].scan_type.realbits = CROS_EC_SENSOR_BITS;\ > + channel[idx].scan_type.storagebits = CROS_EC_SENSOR_BITS;\ > + channel[idx].scan_type.shift = 0;\ No need to define the 'obvious' 0 shift case. These must already be initialized to zero or all sorts of things are going to potentially break. > + channel[idx].scan_index = idx;\ > + channel[idx].ext_info = cros_ec_sensors_ext_info;\ > + channel[idx].scan_type.sign = 'u'; > + > /** > * cros_ec_motion_send_host_cmd() - send motion sense host command > * @st: pointer to state information for device