root/drivers/iio/accel/ssp_accel_sensor.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ssp_accel_read_raw
  2. ssp_accel_write_raw
  3. ssp_process_accel_data
  4. ssp_accel_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
   4  */
   5 
   6 #include <linux/iio/common/ssp_sensors.h>
   7 #include <linux/iio/iio.h>
   8 #include <linux/iio/buffer.h>
   9 #include <linux/iio/kfifo_buf.h>
  10 #include <linux/module.h>
  11 #include <linux/platform_device.h>
  12 #include <linux/slab.h>
  13 #include "../common/ssp_sensors/ssp_iio_sensor.h"
  14 
  15 #define SSP_CHANNEL_COUNT 3
  16 
  17 #define SSP_ACCEL_NAME "ssp-accelerometer"
  18 static const char ssp_accel_device_name[] = SSP_ACCEL_NAME;
  19 
  20 enum ssp_accel_3d_channel {
  21         SSP_CHANNEL_SCAN_INDEX_X,
  22         SSP_CHANNEL_SCAN_INDEX_Y,
  23         SSP_CHANNEL_SCAN_INDEX_Z,
  24         SSP_CHANNEL_SCAN_INDEX_TIME,
  25 };
  26 
  27 static int ssp_accel_read_raw(struct iio_dev *indio_dev,
  28                               struct iio_chan_spec const *chan,  int *val,
  29                               int *val2, long mask)
  30 {
  31         u32 t;
  32         struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
  33 
  34         switch (mask) {
  35         case IIO_CHAN_INFO_SAMP_FREQ:
  36                 t = ssp_get_sensor_delay(data, SSP_ACCELEROMETER_SENSOR);
  37                 ssp_convert_to_freq(t, val, val2);
  38                 return IIO_VAL_INT_PLUS_MICRO;
  39         default:
  40                 break;
  41         }
  42 
  43         return -EINVAL;
  44 }
  45 
  46 static int ssp_accel_write_raw(struct iio_dev *indio_dev,
  47                                struct iio_chan_spec const *chan, int val,
  48                                int val2, long mask)
  49 {
  50         int ret;
  51         struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
  52 
  53         switch (mask) {
  54         case IIO_CHAN_INFO_SAMP_FREQ:
  55                 ret = ssp_convert_to_time(val, val2);
  56                 ret = ssp_change_delay(data, SSP_ACCELEROMETER_SENSOR, ret);
  57                 if (ret < 0)
  58                         dev_err(&indio_dev->dev, "accel sensor enable fail\n");
  59 
  60                 return ret;
  61         default:
  62                 break;
  63         }
  64 
  65         return -EINVAL;
  66 }
  67 
  68 static const struct iio_info ssp_accel_iio_info = {
  69         .read_raw = &ssp_accel_read_raw,
  70         .write_raw = &ssp_accel_write_raw,
  71 };
  72 
  73 static const unsigned long ssp_accel_scan_mask[] = { 0x7, 0, };
  74 
  75 static const struct iio_chan_spec ssp_acc_channels[] = {
  76         SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
  77         SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
  78         SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
  79         SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
  80 };
  81 
  82 static int ssp_process_accel_data(struct iio_dev *indio_dev, void *buf,
  83                                   int64_t timestamp)
  84 {
  85         return ssp_common_process_data(indio_dev, buf, SSP_ACCELEROMETER_SIZE,
  86                                        timestamp);
  87 }
  88 
  89 static const struct iio_buffer_setup_ops ssp_accel_buffer_ops = {
  90         .postenable = &ssp_common_buffer_postenable,
  91         .postdisable = &ssp_common_buffer_postdisable,
  92 };
  93 
  94 static int ssp_accel_probe(struct platform_device *pdev)
  95 {
  96         int ret;
  97         struct iio_dev *indio_dev;
  98         struct ssp_sensor_data *spd;
  99         struct iio_buffer *buffer;
 100 
 101         indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));
 102         if (!indio_dev)
 103                 return -ENOMEM;
 104 
 105         spd = iio_priv(indio_dev);
 106 
 107         spd->process_data = ssp_process_accel_data;
 108         spd->type = SSP_ACCELEROMETER_SENSOR;
 109 
 110         indio_dev->name = ssp_accel_device_name;
 111         indio_dev->dev.parent = &pdev->dev;
 112         indio_dev->dev.of_node = pdev->dev.of_node;
 113         indio_dev->info = &ssp_accel_iio_info;
 114         indio_dev->modes = INDIO_BUFFER_SOFTWARE;
 115         indio_dev->channels = ssp_acc_channels;
 116         indio_dev->num_channels = ARRAY_SIZE(ssp_acc_channels);
 117         indio_dev->available_scan_masks = ssp_accel_scan_mask;
 118 
 119         buffer = devm_iio_kfifo_allocate(&pdev->dev);
 120         if (!buffer)
 121                 return -ENOMEM;
 122 
 123         iio_device_attach_buffer(indio_dev, buffer);
 124 
 125         indio_dev->setup_ops = &ssp_accel_buffer_ops;
 126 
 127         platform_set_drvdata(pdev, indio_dev);
 128 
 129         ret = devm_iio_device_register(&pdev->dev, indio_dev);
 130         if (ret < 0)
 131                 return ret;
 132 
 133         /* ssp registering should be done after all iio setup */
 134         ssp_register_consumer(indio_dev, SSP_ACCELEROMETER_SENSOR);
 135 
 136         return 0;
 137 }
 138 
 139 static struct platform_driver ssp_accel_driver = {
 140         .driver = {
 141                 .name = SSP_ACCEL_NAME,
 142         },
 143         .probe = ssp_accel_probe,
 144 };
 145 
 146 module_platform_driver(ssp_accel_driver);
 147 
 148 MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");
 149 MODULE_DESCRIPTION("Samsung sensorhub accelerometers driver");
 150 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */