To avoid code duplication, we move channels initialization in cros_ec_sensors_core. Signed-off-by: Fabien Lahoudere <fabien.lahoudere@xxxxxxxxxxxxx> --- .../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); + 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;\ + 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 -- 2.20.1