cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

st_gyro_core.c (12102B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * STMicroelectronics gyroscopes driver
      4 *
      5 * Copyright 2012-2013 STMicroelectronics Inc.
      6 *
      7 * Denis Ciocca <denis.ciocca@st.com>
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/mutex.h>
     13#include <linux/interrupt.h>
     14#include <linux/sysfs.h>
     15#include <linux/iio/iio.h>
     16#include <linux/iio/sysfs.h>
     17#include <linux/iio/trigger.h>
     18
     19#include <linux/iio/common/st_sensors.h>
     20#include "st_gyro.h"
     21
     22#define ST_GYRO_NUMBER_DATA_CHANNELS		3
     23
     24/* DEFAULT VALUE FOR SENSORS */
     25#define ST_GYRO_DEFAULT_OUT_X_L_ADDR		0x28
     26#define ST_GYRO_DEFAULT_OUT_Y_L_ADDR		0x2a
     27#define ST_GYRO_DEFAULT_OUT_Z_L_ADDR		0x2c
     28
     29/* FULLSCALE */
     30#define ST_GYRO_FS_AVL_245DPS			245
     31#define ST_GYRO_FS_AVL_250DPS			250
     32#define ST_GYRO_FS_AVL_500DPS			500
     33#define ST_GYRO_FS_AVL_2000DPS			2000
     34
     35static const struct iio_mount_matrix *
     36st_gyro_get_mount_matrix(const struct iio_dev *indio_dev,
     37			 const struct iio_chan_spec *chan)
     38{
     39	struct st_sensor_data *gdata = iio_priv(indio_dev);
     40
     41	return &gdata->mount_matrix;
     42}
     43
     44static const struct iio_chan_spec_ext_info st_gyro_mount_matrix_ext_info[] = {
     45	IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_gyro_get_mount_matrix),
     46	{ }
     47};
     48
     49static const struct iio_chan_spec st_gyro_16bit_channels[] = {
     50	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
     51			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
     52			ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
     53			ST_GYRO_DEFAULT_OUT_X_L_ADDR,
     54			st_gyro_mount_matrix_ext_info),
     55	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
     56			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
     57			ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
     58			ST_GYRO_DEFAULT_OUT_Y_L_ADDR,
     59			st_gyro_mount_matrix_ext_info),
     60	ST_SENSORS_LSM_CHANNELS_EXT(IIO_ANGL_VEL,
     61			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
     62			ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
     63			ST_GYRO_DEFAULT_OUT_Z_L_ADDR,
     64			st_gyro_mount_matrix_ext_info),
     65	IIO_CHAN_SOFT_TIMESTAMP(3)
     66};
     67
     68static const struct st_sensor_settings st_gyro_sensors_settings[] = {
     69	{
     70		.wai = 0xd3,
     71		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
     72		.sensors_supported = {
     73			[0] = L3G4200D_GYRO_DEV_NAME,
     74			[1] = LSM330DL_GYRO_DEV_NAME,
     75		},
     76		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
     77		.odr = {
     78			.addr = 0x20,
     79			.mask = 0xc0,
     80			.odr_avl = {
     81				{ .hz = 100, .value = 0x00, },
     82				{ .hz = 200, .value = 0x01, },
     83				{ .hz = 400, .value = 0x02, },
     84				{ .hz = 800, .value = 0x03, },
     85			},
     86		},
     87		.pw = {
     88			.addr = 0x20,
     89			.mask = 0x08,
     90			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
     91			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
     92		},
     93		.enable_axis = {
     94			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
     95			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
     96		},
     97		.fs = {
     98			.addr = 0x23,
     99			.mask = 0x30,
    100			.fs_avl = {
    101				[0] = {
    102					.num = ST_GYRO_FS_AVL_250DPS,
    103					.value = 0x00,
    104					.gain = IIO_DEGREE_TO_RAD(8750),
    105				},
    106				[1] = {
    107					.num = ST_GYRO_FS_AVL_500DPS,
    108					.value = 0x01,
    109					.gain = IIO_DEGREE_TO_RAD(17500),
    110				},
    111				[2] = {
    112					.num = ST_GYRO_FS_AVL_2000DPS,
    113					.value = 0x02,
    114					.gain = IIO_DEGREE_TO_RAD(70000),
    115				},
    116			},
    117		},
    118		.bdu = {
    119			.addr = 0x23,
    120			.mask = 0x80,
    121		},
    122		.drdy_irq = {
    123			.int2 = {
    124				.addr = 0x22,
    125				.mask = 0x08,
    126			},
    127			/*
    128			 * The sensor has IHL (active low) and open
    129			 * drain settings, but only for INT1 and not
    130			 * for the DRDY line on INT2.
    131			 */
    132			.stat_drdy = {
    133				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
    134				.mask = 0x07,
    135			},
    136		},
    137		.sim = {
    138			.addr = 0x23,
    139			.value = BIT(0),
    140		},
    141		.multi_read_bit = true,
    142		.bootime = 2,
    143	},
    144	{
    145		.wai = 0xd4,
    146		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
    147		.sensors_supported = {
    148			[0] = L3GD20_GYRO_DEV_NAME,
    149			[1] = LSM330D_GYRO_DEV_NAME,
    150			[2] = LSM330DLC_GYRO_DEV_NAME,
    151			[3] = L3G4IS_GYRO_DEV_NAME,
    152			[4] = LSM330_GYRO_DEV_NAME,
    153		},
    154		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
    155		.odr = {
    156			.addr = 0x20,
    157			.mask = 0xc0,
    158			.odr_avl = {
    159				{ .hz = 95, .value = 0x00, },
    160				{ .hz = 190, .value = 0x01, },
    161				{ .hz = 380, .value = 0x02, },
    162				{ .hz = 760, .value = 0x03, },
    163			},
    164		},
    165		.pw = {
    166			.addr = 0x20,
    167			.mask = 0x08,
    168			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
    169			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
    170		},
    171		.enable_axis = {
    172			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
    173			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
    174		},
    175		.fs = {
    176			.addr = 0x23,
    177			.mask = 0x30,
    178			.fs_avl = {
    179				[0] = {
    180					.num = ST_GYRO_FS_AVL_250DPS,
    181					.value = 0x00,
    182					.gain = IIO_DEGREE_TO_RAD(8750),
    183				},
    184				[1] = {
    185					.num = ST_GYRO_FS_AVL_500DPS,
    186					.value = 0x01,
    187					.gain = IIO_DEGREE_TO_RAD(17500),
    188				},
    189				[2] = {
    190					.num = ST_GYRO_FS_AVL_2000DPS,
    191					.value = 0x02,
    192					.gain = IIO_DEGREE_TO_RAD(70000),
    193				},
    194			},
    195		},
    196		.bdu = {
    197			.addr = 0x23,
    198			.mask = 0x80,
    199		},
    200		.drdy_irq = {
    201			.int2 = {
    202				.addr = 0x22,
    203				.mask = 0x08,
    204			},
    205			/*
    206			 * The sensor has IHL (active low) and open
    207			 * drain settings, but only for INT1 and not
    208			 * for the DRDY line on INT2.
    209			 */
    210			.stat_drdy = {
    211				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
    212				.mask = 0x07,
    213			},
    214		},
    215		.sim = {
    216			.addr = 0x23,
    217			.value = BIT(0),
    218		},
    219		.multi_read_bit = true,
    220		.bootime = 2,
    221	},
    222	{
    223		.wai = 0xd4,
    224		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
    225		.sensors_supported = {
    226			[0] = LSM9DS0_GYRO_DEV_NAME,
    227		},
    228		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
    229		.odr = {
    230			.addr = 0x20,
    231			.mask = GENMASK(7, 6),
    232			.odr_avl = {
    233				{ .hz = 95, .value = 0x00, },
    234				{ .hz = 190, .value = 0x01, },
    235				{ .hz = 380, .value = 0x02, },
    236				{ .hz = 760, .value = 0x03, },
    237			},
    238		},
    239		.pw = {
    240			.addr = 0x20,
    241			.mask = BIT(3),
    242			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
    243			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
    244		},
    245		.enable_axis = {
    246			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
    247			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
    248		},
    249		.fs = {
    250			.addr = 0x23,
    251			.mask = GENMASK(5, 4),
    252			.fs_avl = {
    253				[0] = {
    254					.num = ST_GYRO_FS_AVL_245DPS,
    255					.value = 0x00,
    256					.gain = IIO_DEGREE_TO_RAD(8750),
    257				},
    258				[1] = {
    259					.num = ST_GYRO_FS_AVL_500DPS,
    260					.value = 0x01,
    261					.gain = IIO_DEGREE_TO_RAD(17500),
    262				},
    263				[2] = {
    264					.num = ST_GYRO_FS_AVL_2000DPS,
    265					.value = 0x02,
    266					.gain = IIO_DEGREE_TO_RAD(70000),
    267				},
    268			},
    269		},
    270		.bdu = {
    271			.addr = 0x23,
    272			.mask = BIT(7),
    273		},
    274		.drdy_irq = {
    275			.int2 = {
    276				.addr = 0x22,
    277				.mask = BIT(3),
    278			},
    279			/*
    280			 * The sensor has IHL (active low) and open
    281			 * drain settings, but only for INT1 and not
    282			 * for the DRDY line on INT2.
    283			 */
    284			.stat_drdy = {
    285				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
    286				.mask = GENMASK(2, 0),
    287			},
    288		},
    289		.sim = {
    290			.addr = 0x23,
    291			.value = BIT(0),
    292		},
    293		.multi_read_bit = true,
    294		.bootime = 2,
    295	},
    296	{
    297		.wai = 0xd7,
    298		.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
    299		.sensors_supported = {
    300			[0] = L3GD20H_GYRO_DEV_NAME,
    301		},
    302		.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
    303		.odr = {
    304			.addr = 0x20,
    305			.mask = 0xc0,
    306			.odr_avl = {
    307				{ .hz = 100, .value = 0x00, },
    308				{ .hz = 200, .value = 0x01, },
    309				{ .hz = 400, .value = 0x02, },
    310				{ .hz = 800, .value = 0x03, },
    311			},
    312		},
    313		.pw = {
    314			.addr = 0x20,
    315			.mask = 0x08,
    316			.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
    317			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
    318		},
    319		.enable_axis = {
    320			.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
    321			.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
    322		},
    323		.fs = {
    324			.addr = 0x23,
    325			.mask = 0x30,
    326			.fs_avl = {
    327				[0] = {
    328					.num = ST_GYRO_FS_AVL_245DPS,
    329					.value = 0x00,
    330					.gain = IIO_DEGREE_TO_RAD(8750),
    331				},
    332				[1] = {
    333					.num = ST_GYRO_FS_AVL_500DPS,
    334					.value = 0x01,
    335					.gain = IIO_DEGREE_TO_RAD(17500),
    336				},
    337				[2] = {
    338					.num = ST_GYRO_FS_AVL_2000DPS,
    339					.value = 0x02,
    340					.gain = IIO_DEGREE_TO_RAD(70000),
    341				},
    342			},
    343		},
    344		.bdu = {
    345			.addr = 0x23,
    346			.mask = 0x80,
    347		},
    348		.drdy_irq = {
    349			.int2 = {
    350				.addr = 0x22,
    351				.mask = 0x08,
    352			},
    353			/*
    354			 * The sensor has IHL (active low) and open
    355			 * drain settings, but only for INT1 and not
    356			 * for the DRDY line on INT2.
    357			 */
    358			.stat_drdy = {
    359				.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
    360				.mask = 0x07,
    361			},
    362		},
    363		.sim = {
    364			.addr = 0x23,
    365			.value = BIT(0),
    366		},
    367		.multi_read_bit = true,
    368		.bootime = 2,
    369	},
    370};
    371
    372/* DRDY on gyros is available only on INT2 pin */
    373static const struct st_sensors_platform_data gyro_pdata = {
    374	.drdy_int_pin = 2,
    375};
    376
    377static int st_gyro_read_raw(struct iio_dev *indio_dev,
    378			struct iio_chan_spec const *ch, int *val,
    379							int *val2, long mask)
    380{
    381	int err;
    382	struct st_sensor_data *gdata = iio_priv(indio_dev);
    383
    384	switch (mask) {
    385	case IIO_CHAN_INFO_RAW:
    386		err = st_sensors_read_info_raw(indio_dev, ch, val);
    387		if (err < 0)
    388			goto read_error;
    389
    390		return IIO_VAL_INT;
    391	case IIO_CHAN_INFO_SCALE:
    392		*val = 0;
    393		*val2 = gdata->current_fullscale->gain;
    394		return IIO_VAL_INT_PLUS_MICRO;
    395	case IIO_CHAN_INFO_SAMP_FREQ:
    396		*val = gdata->odr;
    397		return IIO_VAL_INT;
    398	default:
    399		return -EINVAL;
    400	}
    401
    402read_error:
    403	return err;
    404}
    405
    406static int st_gyro_write_raw(struct iio_dev *indio_dev,
    407		struct iio_chan_spec const *chan, int val, int val2, long mask)
    408{
    409	switch (mask) {
    410	case IIO_CHAN_INFO_SCALE:
    411		return st_sensors_set_fullscale_by_gain(indio_dev, val2);
    412	case IIO_CHAN_INFO_SAMP_FREQ:
    413		if (val2)
    414			return -EINVAL;
    415
    416		return st_sensors_set_odr(indio_dev, val);
    417	default:
    418		return -EINVAL;
    419	}
    420}
    421
    422static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
    423static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_anglvel_scale_available);
    424
    425static struct attribute *st_gyro_attributes[] = {
    426	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
    427	&iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
    428	NULL,
    429};
    430
    431static const struct attribute_group st_gyro_attribute_group = {
    432	.attrs = st_gyro_attributes,
    433};
    434
    435static const struct iio_info gyro_info = {
    436	.attrs = &st_gyro_attribute_group,
    437	.read_raw = &st_gyro_read_raw,
    438	.write_raw = &st_gyro_write_raw,
    439	.debugfs_reg_access = &st_sensors_debugfs_reg_access,
    440};
    441
    442#ifdef CONFIG_IIO_TRIGGER
    443static const struct iio_trigger_ops st_gyro_trigger_ops = {
    444	.set_trigger_state = ST_GYRO_TRIGGER_SET_STATE,
    445	.validate_device = st_sensors_validate_device,
    446};
    447#define ST_GYRO_TRIGGER_OPS (&st_gyro_trigger_ops)
    448#else
    449#define ST_GYRO_TRIGGER_OPS NULL
    450#endif
    451
    452/*
    453 * st_gyro_get_settings() - get sensor settings from device name
    454 * @name: device name buffer reference.
    455 *
    456 * Return: valid reference on success, NULL otherwise.
    457 */
    458const struct st_sensor_settings *st_gyro_get_settings(const char *name)
    459{
    460	int index = st_sensors_get_settings_index(name,
    461					st_gyro_sensors_settings,
    462					ARRAY_SIZE(st_gyro_sensors_settings));
    463	if (index < 0)
    464		return NULL;
    465
    466	return &st_gyro_sensors_settings[index];
    467}
    468EXPORT_SYMBOL_NS(st_gyro_get_settings, IIO_ST_SENSORS);
    469
    470int st_gyro_common_probe(struct iio_dev *indio_dev)
    471{
    472	struct st_sensor_data *gdata = iio_priv(indio_dev);
    473	struct st_sensors_platform_data *pdata;
    474	struct device *parent = indio_dev->dev.parent;
    475	int err;
    476
    477	indio_dev->modes = INDIO_DIRECT_MODE;
    478	indio_dev->info = &gyro_info;
    479
    480	err = st_sensors_verify_id(indio_dev);
    481	if (err < 0)
    482		return err;
    483
    484	gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
    485	indio_dev->channels = gdata->sensor_settings->ch;
    486	indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
    487
    488	err = iio_read_mount_matrix(parent, &gdata->mount_matrix);
    489	if (err)
    490		return err;
    491
    492	gdata->current_fullscale = &gdata->sensor_settings->fs.fs_avl[0];
    493	gdata->odr = gdata->sensor_settings->odr.odr_avl[0].hz;
    494
    495	pdata = (struct st_sensors_platform_data *)&gyro_pdata;
    496
    497	err = st_sensors_init_sensor(indio_dev, pdata);
    498	if (err < 0)
    499		return err;
    500
    501	err = st_gyro_allocate_ring(indio_dev);
    502	if (err < 0)
    503		return err;
    504
    505	if (gdata->irq > 0) {
    506		err = st_sensors_allocate_trigger(indio_dev,
    507						  ST_GYRO_TRIGGER_OPS);
    508		if (err < 0)
    509			return err;
    510	}
    511
    512	return devm_iio_device_register(parent, indio_dev);
    513}
    514EXPORT_SYMBOL_NS(st_gyro_common_probe, IIO_ST_SENSORS);
    515
    516MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
    517MODULE_DESCRIPTION("STMicroelectronics gyroscopes driver");
    518MODULE_LICENSE("GPL v2");
    519MODULE_IMPORT_NS(IIO_ST_SENSORS);