Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
0004  */
0005 
0006 #include <linux/iio/common/ssp_sensors.h>
0007 #include <linux/iio/iio.h>
0008 #include <linux/iio/buffer.h>
0009 #include <linux/iio/kfifo_buf.h>
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/slab.h>
0013 #include "../common/ssp_sensors/ssp_iio_sensor.h"
0014 
0015 #define SSP_CHANNEL_COUNT 3
0016 
0017 #define SSP_GYROSCOPE_NAME "ssp-gyroscope"
0018 static const char ssp_gyro_name[] = SSP_GYROSCOPE_NAME;
0019 
0020 enum ssp_gyro_3d_channel {
0021     SSP_CHANNEL_SCAN_INDEX_X,
0022     SSP_CHANNEL_SCAN_INDEX_Y,
0023     SSP_CHANNEL_SCAN_INDEX_Z,
0024     SSP_CHANNEL_SCAN_INDEX_TIME,
0025 };
0026 
0027 static int ssp_gyro_read_raw(struct iio_dev *indio_dev,
0028                  struct iio_chan_spec const *chan, int *val,
0029                  int *val2, long mask)
0030 {
0031     u32 t;
0032     struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
0033 
0034     switch (mask) {
0035     case IIO_CHAN_INFO_SAMP_FREQ:
0036         t = ssp_get_sensor_delay(data, SSP_GYROSCOPE_SENSOR);
0037         ssp_convert_to_freq(t, val, val2);
0038         return IIO_VAL_INT_PLUS_MICRO;
0039     default:
0040         break;
0041     }
0042 
0043     return -EINVAL;
0044 }
0045 
0046 static int ssp_gyro_write_raw(struct iio_dev *indio_dev,
0047                   struct iio_chan_spec const *chan, int val,
0048                   int val2, long mask)
0049 {
0050     int ret;
0051     struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
0052 
0053     switch (mask) {
0054     case IIO_CHAN_INFO_SAMP_FREQ:
0055         ret = ssp_convert_to_time(val, val2);
0056         ret = ssp_change_delay(data, SSP_GYROSCOPE_SENSOR, ret);
0057         if (ret < 0)
0058             dev_err(&indio_dev->dev, "gyro sensor enable fail\n");
0059 
0060         return ret;
0061     default:
0062         break;
0063     }
0064 
0065     return -EINVAL;
0066 }
0067 
0068 static const struct iio_info ssp_gyro_iio_info = {
0069     .read_raw = &ssp_gyro_read_raw,
0070     .write_raw = &ssp_gyro_write_raw,
0071 };
0072 
0073 static const unsigned long ssp_gyro_scan_mask[] = { 0x07, 0, };
0074 
0075 static const struct iio_chan_spec ssp_gyro_channels[] = {
0076     SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
0077     SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
0078     SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
0079     SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
0080 };
0081 
0082 static int ssp_process_gyro_data(struct iio_dev *indio_dev, void *buf,
0083                  int64_t timestamp)
0084 {
0085     return ssp_common_process_data(indio_dev, buf, SSP_GYROSCOPE_SIZE,
0086                        timestamp);
0087 }
0088 
0089 static const struct iio_buffer_setup_ops ssp_gyro_buffer_ops = {
0090     .postenable = &ssp_common_buffer_postenable,
0091     .postdisable = &ssp_common_buffer_postdisable,
0092 };
0093 
0094 static int ssp_gyro_probe(struct platform_device *pdev)
0095 {
0096     int ret;
0097     struct iio_dev *indio_dev;
0098     struct ssp_sensor_data *spd;
0099 
0100     indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
0101     if (!indio_dev)
0102         return -ENOMEM;
0103 
0104     spd = iio_priv(indio_dev);
0105 
0106     spd->process_data = ssp_process_gyro_data;
0107     spd->type = SSP_GYROSCOPE_SENSOR;
0108 
0109     indio_dev->name = ssp_gyro_name;
0110     indio_dev->info = &ssp_gyro_iio_info;
0111     indio_dev->channels = ssp_gyro_channels;
0112     indio_dev->num_channels = ARRAY_SIZE(ssp_gyro_channels);
0113     indio_dev->available_scan_masks = ssp_gyro_scan_mask;
0114 
0115     ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev,
0116                       &ssp_gyro_buffer_ops);
0117     if (ret)
0118         return ret;
0119 
0120     platform_set_drvdata(pdev, indio_dev);
0121 
0122     ret = devm_iio_device_register(&pdev->dev, indio_dev);
0123     if (ret < 0)
0124         return ret;
0125 
0126     /* ssp registering should be done after all iio setup */
0127     ssp_register_consumer(indio_dev, SSP_GYROSCOPE_SENSOR);
0128 
0129     return 0;
0130 }
0131 
0132 static struct platform_driver ssp_gyro_driver = {
0133     .driver = {
0134         .name = SSP_GYROSCOPE_NAME,
0135     },
0136     .probe = ssp_gyro_probe,
0137 };
0138 
0139 module_platform_driver(ssp_gyro_driver);
0140 
0141 MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
0142 MODULE_DESCRIPTION("Samsung sensorhub gyroscopes driver");
0143 MODULE_LICENSE("GPL");
0144 MODULE_IMPORT_NS(IIO_SSP_SENSORS);