145 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 316 17#define SSP_GYROSCOPE_NAME "ssp-gyroscope"18static const char ssp_gyro_name[] = SSP_GYROSCOPE_NAME;19 20enum ssp_gyro_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 27static int ssp_gyro_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_GYROSCOPE_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 46static int ssp_gyro_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_GYROSCOPE_SENSOR, ret);57 if (ret < 0)58 dev_err(&indio_dev->dev, "gyro sensor enable fail\n");59 60 return ret;61 default:62 break;63 }64 65 return -EINVAL;66}67 68static const struct iio_info ssp_gyro_iio_info = {69 .read_raw = &ssp_gyro_read_raw,70 .write_raw = &ssp_gyro_write_raw,71};72 73static const unsigned long ssp_gyro_scan_mask[] = { 0x07, 0, };74 75static const struct iio_chan_spec ssp_gyro_channels[] = {76 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),77 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),78 SSP_CHANNEL_AG(IIO_ANGL_VEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),79 SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),80};81 82static int ssp_process_gyro_data(struct iio_dev *indio_dev, void *buf,83 int64_t timestamp)84{85 return ssp_common_process_data(indio_dev, buf, SSP_GYROSCOPE_SIZE,86 timestamp);87}88 89static const struct iio_buffer_setup_ops ssp_gyro_buffer_ops = {90 .postenable = &ssp_common_buffer_postenable,91 .postdisable = &ssp_common_buffer_postdisable,92};93 94static int ssp_gyro_probe(struct platform_device *pdev)95{96 int ret;97 struct iio_dev *indio_dev;98 struct ssp_sensor_data *spd;99 100 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*spd));101 if (!indio_dev)102 return -ENOMEM;103 104 spd = iio_priv(indio_dev);105 106 spd->process_data = ssp_process_gyro_data;107 spd->type = SSP_GYROSCOPE_SENSOR;108 109 indio_dev->name = ssp_gyro_name;110 indio_dev->info = &ssp_gyro_iio_info;111 indio_dev->channels = ssp_gyro_channels;112 indio_dev->num_channels = ARRAY_SIZE(ssp_gyro_channels);113 indio_dev->available_scan_masks = ssp_gyro_scan_mask;114 115 ret = devm_iio_kfifo_buffer_setup(&pdev->dev, indio_dev,116 &ssp_gyro_buffer_ops);117 if (ret)118 return ret;119 120 platform_set_drvdata(pdev, indio_dev);121 122 ret = devm_iio_device_register(&pdev->dev, indio_dev);123 if (ret < 0)124 return ret;125 126 /* ssp registering should be done after all iio setup */127 ssp_register_consumer(indio_dev, SSP_GYROSCOPE_SENSOR);128 129 return 0;130}131 132static struct platform_driver ssp_gyro_driver = {133 .driver = {134 .name = SSP_GYROSCOPE_NAME,135 },136 .probe = ssp_gyro_probe,137};138 139module_platform_driver(ssp_gyro_driver);140 141MODULE_AUTHOR("Karol Wrona <k.wrona@samsung.com>");142MODULE_DESCRIPTION("Samsung sensorhub gyroscopes driver");143MODULE_LICENSE("GPL");144MODULE_IMPORT_NS(IIO_SSP_SENSORS);145