162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Murata SCA3300 3-axis industrial accelerometer
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2021 Vaisala Oyj. All rights reserved.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/bitops.h>
962306a36Sopenharmony_ci#include <linux/crc8.h>
1062306a36Sopenharmony_ci#include <linux/delay.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/module.h>
1362306a36Sopenharmony_ci#include <linux/spi/spi.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <asm/unaligned.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <linux/iio/buffer.h>
1862306a36Sopenharmony_ci#include <linux/iio/iio.h>
1962306a36Sopenharmony_ci#include <linux/iio/sysfs.h>
2062306a36Sopenharmony_ci#include <linux/iio/trigger_consumer.h>
2162306a36Sopenharmony_ci#include <linux/iio/triggered_buffer.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define SCA3300_ALIAS "sca3300"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define SCA3300_CRC8_POLYNOMIAL 0x1d
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* Device mode register */
2862306a36Sopenharmony_ci#define SCA3300_REG_MODE	0xd
2962306a36Sopenharmony_ci#define SCA3300_MODE_SW_RESET	0x20
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* Last register in map */
3262306a36Sopenharmony_ci#define SCA3300_REG_SELBANK	0x1f
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/* Device status and mask */
3562306a36Sopenharmony_ci#define SCA3300_REG_STATUS	0x6
3662306a36Sopenharmony_ci#define SCA3300_STATUS_MASK	GENMASK(8, 0)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* Device ID */
3962306a36Sopenharmony_ci#define SCA3300_REG_WHOAMI	0x10
4062306a36Sopenharmony_ci#define SCA3300_WHOAMI_ID	0x51
4162306a36Sopenharmony_ci#define SCL3300_WHOAMI_ID	0xC1
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/* Device return status and mask */
4462306a36Sopenharmony_ci#define SCA3300_VALUE_RS_ERROR	0x3
4562306a36Sopenharmony_ci#define SCA3300_MASK_RS_STATUS	GENMASK(1, 0)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#define SCL3300_REG_ANG_CTRL 0x0C
4862306a36Sopenharmony_ci#define SCL3300_ANG_ENABLE   0x1F
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cienum sca3300_scan_indexes {
5162306a36Sopenharmony_ci	SCA3300_ACC_X = 0,
5262306a36Sopenharmony_ci	SCA3300_ACC_Y,
5362306a36Sopenharmony_ci	SCA3300_ACC_Z,
5462306a36Sopenharmony_ci	SCA3300_TEMP,
5562306a36Sopenharmony_ci	SCA3300_INCLI_X,
5662306a36Sopenharmony_ci	SCA3300_INCLI_Y,
5762306a36Sopenharmony_ci	SCA3300_INCLI_Z,
5862306a36Sopenharmony_ci	SCA3300_SCAN_MAX
5962306a36Sopenharmony_ci};
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/*
6262306a36Sopenharmony_ci * Buffer size max case:
6362306a36Sopenharmony_ci * Three accel channels, two bytes per channel.
6462306a36Sopenharmony_ci * Temperature channel, two bytes.
6562306a36Sopenharmony_ci * Three incli channels, two bytes per channel.
6662306a36Sopenharmony_ci * Timestamp channel, eight bytes.
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_ci#define SCA3300_MAX_BUFFER_SIZE (ALIGN(sizeof(s16) * SCA3300_SCAN_MAX, sizeof(s64)) + sizeof(s64))
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#define SCA3300_ACCEL_CHANNEL(index, reg, axis) {			\
7162306a36Sopenharmony_ci	.type = IIO_ACCEL,						\
7262306a36Sopenharmony_ci	.address = reg,							\
7362306a36Sopenharmony_ci	.modified = 1,							\
7462306a36Sopenharmony_ci	.channel2 = IIO_MOD_##axis,					\
7562306a36Sopenharmony_ci	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
7662306a36Sopenharmony_ci	.info_mask_shared_by_type =					\
7762306a36Sopenharmony_ci	BIT(IIO_CHAN_INFO_SCALE) |					\
7862306a36Sopenharmony_ci	BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),		\
7962306a36Sopenharmony_ci	.info_mask_shared_by_type_available =				\
8062306a36Sopenharmony_ci	BIT(IIO_CHAN_INFO_SCALE) |					\
8162306a36Sopenharmony_ci	BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),		\
8262306a36Sopenharmony_ci	.scan_index = index,						\
8362306a36Sopenharmony_ci	.scan_type = {							\
8462306a36Sopenharmony_ci		.sign = 's',						\
8562306a36Sopenharmony_ci		.realbits = 16,						\
8662306a36Sopenharmony_ci		.storagebits = 16,					\
8762306a36Sopenharmony_ci		.endianness = IIO_CPU,					\
8862306a36Sopenharmony_ci	},								\
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define SCA3300_INCLI_CHANNEL(index, reg, axis) {			\
9262306a36Sopenharmony_ci	.type = IIO_INCLI,						\
9362306a36Sopenharmony_ci	.address = reg,							\
9462306a36Sopenharmony_ci	.modified = 1,							\
9562306a36Sopenharmony_ci	.channel2 = IIO_MOD_##axis,					\
9662306a36Sopenharmony_ci	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
9762306a36Sopenharmony_ci	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
9862306a36Sopenharmony_ci	.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
9962306a36Sopenharmony_ci	.scan_index = index,						\
10062306a36Sopenharmony_ci	.scan_type = {							\
10162306a36Sopenharmony_ci		.sign = 's',						\
10262306a36Sopenharmony_ci		.realbits = 16,						\
10362306a36Sopenharmony_ci		.storagebits = 16,					\
10462306a36Sopenharmony_ci		.endianness = IIO_CPU,					\
10562306a36Sopenharmony_ci	},								\
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci#define SCA3300_TEMP_CHANNEL(index, reg) {				\
10962306a36Sopenharmony_ci		.type = IIO_TEMP,					\
11062306a36Sopenharmony_ci		.address = reg,						\
11162306a36Sopenharmony_ci		.scan_index = index,					\
11262306a36Sopenharmony_ci		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
11362306a36Sopenharmony_ci		.scan_type = {						\
11462306a36Sopenharmony_ci			.sign = 's',					\
11562306a36Sopenharmony_ci			.realbits = 16,					\
11662306a36Sopenharmony_ci			.storagebits = 16,				\
11762306a36Sopenharmony_ci			.endianness = IIO_CPU,				\
11862306a36Sopenharmony_ci		},							\
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_cistatic const struct iio_chan_spec sca3300_channels[] = {
12262306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_X, 0x1, X),
12362306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_Y, 0x2, Y),
12462306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_Z, 0x3, Z),
12562306a36Sopenharmony_ci	SCA3300_TEMP_CHANNEL(SCA3300_TEMP, 0x05),
12662306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(4),
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic const int sca3300_lp_freq[] = {70, 10};
13062306a36Sopenharmony_cistatic const int sca3300_lp_freq_map[] = {0, 0, 0, 1};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic const int scl3300_lp_freq[] = {40, 70, 10};
13362306a36Sopenharmony_cistatic const int scl3300_lp_freq_map[] = {0, 1, 2};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic const int sca3300_accel_scale[][2] = {{0, 370}, {0, 741}, {0, 185}};
13662306a36Sopenharmony_cistatic const int sca3300_accel_scale_map[] = {0, 1, 2, 2};
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cistatic const int scl3300_accel_scale[][2] = {{0, 167}, {0, 333}, {0, 83}};
13962306a36Sopenharmony_cistatic const int scl3300_accel_scale_map[] = {0, 1, 2};
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cistatic const int scl3300_incli_scale[][2] = {{0, 5495}};
14262306a36Sopenharmony_cistatic const int scl3300_incli_scale_map[] = {0, 0, 0};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic const int sca3300_avail_modes_map[] = {0, 1, 2, 3};
14562306a36Sopenharmony_cistatic const int scl3300_avail_modes_map[] = {0, 1, 3};
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic const struct iio_chan_spec scl3300_channels[] = {
14862306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_X, 0x1, X),
14962306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_Y, 0x2, Y),
15062306a36Sopenharmony_ci	SCA3300_ACCEL_CHANNEL(SCA3300_ACC_Z, 0x3, Z),
15162306a36Sopenharmony_ci	SCA3300_TEMP_CHANNEL(SCA3300_TEMP, 0x05),
15262306a36Sopenharmony_ci	SCA3300_INCLI_CHANNEL(SCA3300_INCLI_X, 0x09, X),
15362306a36Sopenharmony_ci	SCA3300_INCLI_CHANNEL(SCA3300_INCLI_Y, 0x0A, Y),
15462306a36Sopenharmony_ci	SCA3300_INCLI_CHANNEL(SCA3300_INCLI_Z, 0x0B, Z),
15562306a36Sopenharmony_ci	IIO_CHAN_SOFT_TIMESTAMP(7),
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic const unsigned long sca3300_scan_masks[] = {
15962306a36Sopenharmony_ci	BIT(SCA3300_ACC_X) | BIT(SCA3300_ACC_Y) | BIT(SCA3300_ACC_Z) |
16062306a36Sopenharmony_ci	BIT(SCA3300_TEMP),
16162306a36Sopenharmony_ci	0
16262306a36Sopenharmony_ci};
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic const unsigned long scl3300_scan_masks[] = {
16562306a36Sopenharmony_ci	BIT(SCA3300_ACC_X) | BIT(SCA3300_ACC_Y) | BIT(SCA3300_ACC_Z) |
16662306a36Sopenharmony_ci	BIT(SCA3300_TEMP) |
16762306a36Sopenharmony_ci	BIT(SCA3300_INCLI_X) | BIT(SCA3300_INCLI_Y) | BIT(SCA3300_INCLI_Z),
16862306a36Sopenharmony_ci	0
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistruct sca3300_chip_info {
17262306a36Sopenharmony_ci	const char *name;
17362306a36Sopenharmony_ci	const unsigned long *scan_masks;
17462306a36Sopenharmony_ci	const struct iio_chan_spec *channels;
17562306a36Sopenharmony_ci	u8 num_channels;
17662306a36Sopenharmony_ci	u8 num_accel_scales;
17762306a36Sopenharmony_ci	const int (*accel_scale)[2];
17862306a36Sopenharmony_ci	const int *accel_scale_map;
17962306a36Sopenharmony_ci	const int (*incli_scale)[2];
18062306a36Sopenharmony_ci	const int *incli_scale_map;
18162306a36Sopenharmony_ci	u8 num_incli_scales;
18262306a36Sopenharmony_ci	u8 num_freqs;
18362306a36Sopenharmony_ci	const int *freq_table;
18462306a36Sopenharmony_ci	const int *freq_map;
18562306a36Sopenharmony_ci	const int *avail_modes_table;
18662306a36Sopenharmony_ci	u8 num_avail_modes;
18762306a36Sopenharmony_ci	u8 chip_id;
18862306a36Sopenharmony_ci	bool angle_supported;
18962306a36Sopenharmony_ci};
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci/**
19262306a36Sopenharmony_ci * struct sca3300_data - device data
19362306a36Sopenharmony_ci * @spi: SPI device structure
19462306a36Sopenharmony_ci * @lock: Data buffer lock
19562306a36Sopenharmony_ci * @chip: Sensor chip specific information
19662306a36Sopenharmony_ci * @buffer: Triggered buffer:
19762306a36Sopenharmony_ci *          -SCA3300: 4 channel 16-bit data + 64-bit timestamp
19862306a36Sopenharmony_ci *          -SCL3300: 7 channel 16-bit data + 64-bit timestamp
19962306a36Sopenharmony_ci * @txbuf: Transmit buffer
20062306a36Sopenharmony_ci * @rxbuf: Receive buffer
20162306a36Sopenharmony_ci */
20262306a36Sopenharmony_cistruct sca3300_data {
20362306a36Sopenharmony_ci	struct spi_device *spi;
20462306a36Sopenharmony_ci	struct mutex lock;
20562306a36Sopenharmony_ci	const struct sca3300_chip_info *chip;
20662306a36Sopenharmony_ci	u8 buffer[SCA3300_MAX_BUFFER_SIZE] __aligned(sizeof(s64));
20762306a36Sopenharmony_ci	u8 txbuf[4] __aligned(IIO_DMA_MINALIGN);
20862306a36Sopenharmony_ci	u8 rxbuf[4];
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic const struct sca3300_chip_info sca3300_chip_tbl[] = {
21262306a36Sopenharmony_ci	{
21362306a36Sopenharmony_ci		.name = "sca3300",
21462306a36Sopenharmony_ci		.scan_masks = sca3300_scan_masks,
21562306a36Sopenharmony_ci		.channels = sca3300_channels,
21662306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(sca3300_channels),
21762306a36Sopenharmony_ci		.num_accel_scales = ARRAY_SIZE(sca3300_accel_scale)*2,
21862306a36Sopenharmony_ci		.accel_scale = sca3300_accel_scale,
21962306a36Sopenharmony_ci		.accel_scale_map = sca3300_accel_scale_map,
22062306a36Sopenharmony_ci		.num_freqs = ARRAY_SIZE(sca3300_lp_freq),
22162306a36Sopenharmony_ci		.freq_table = sca3300_lp_freq,
22262306a36Sopenharmony_ci		.freq_map = sca3300_lp_freq_map,
22362306a36Sopenharmony_ci		.avail_modes_table = sca3300_avail_modes_map,
22462306a36Sopenharmony_ci		.num_avail_modes = 4,
22562306a36Sopenharmony_ci		.chip_id = SCA3300_WHOAMI_ID,
22662306a36Sopenharmony_ci		.angle_supported = false,
22762306a36Sopenharmony_ci	},
22862306a36Sopenharmony_ci	{
22962306a36Sopenharmony_ci		.name = "scl3300",
23062306a36Sopenharmony_ci		.scan_masks = scl3300_scan_masks,
23162306a36Sopenharmony_ci		.channels = scl3300_channels,
23262306a36Sopenharmony_ci		.num_channels = ARRAY_SIZE(scl3300_channels),
23362306a36Sopenharmony_ci		.num_accel_scales = ARRAY_SIZE(scl3300_accel_scale)*2,
23462306a36Sopenharmony_ci		.accel_scale = scl3300_accel_scale,
23562306a36Sopenharmony_ci		.accel_scale_map = scl3300_accel_scale_map,
23662306a36Sopenharmony_ci		.incli_scale = scl3300_incli_scale,
23762306a36Sopenharmony_ci		.incli_scale_map = scl3300_incli_scale_map,
23862306a36Sopenharmony_ci		.num_incli_scales =  ARRAY_SIZE(scl3300_incli_scale)*2,
23962306a36Sopenharmony_ci		.num_freqs = ARRAY_SIZE(scl3300_lp_freq),
24062306a36Sopenharmony_ci		.freq_table = scl3300_lp_freq,
24162306a36Sopenharmony_ci		.freq_map = scl3300_lp_freq_map,
24262306a36Sopenharmony_ci		.avail_modes_table = scl3300_avail_modes_map,
24362306a36Sopenharmony_ci		.num_avail_modes = 3,
24462306a36Sopenharmony_ci		.chip_id = SCL3300_WHOAMI_ID,
24562306a36Sopenharmony_ci		.angle_supported = true,
24662306a36Sopenharmony_ci	},
24762306a36Sopenharmony_ci};
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ciDECLARE_CRC8_TABLE(sca3300_crc_table);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic int sca3300_transfer(struct sca3300_data *sca_data, int *val)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	/* Consecutive requests min. 10 us delay (Datasheet section 5.1.2) */
25462306a36Sopenharmony_ci	struct spi_delay delay = { .value = 10, .unit = SPI_DELAY_UNIT_USECS };
25562306a36Sopenharmony_ci	int32_t ret;
25662306a36Sopenharmony_ci	int rs;
25762306a36Sopenharmony_ci	u8 crc;
25862306a36Sopenharmony_ci	struct spi_transfer xfers[2] = {
25962306a36Sopenharmony_ci		{
26062306a36Sopenharmony_ci			.tx_buf = sca_data->txbuf,
26162306a36Sopenharmony_ci			.len = ARRAY_SIZE(sca_data->txbuf),
26262306a36Sopenharmony_ci			.delay = delay,
26362306a36Sopenharmony_ci			.cs_change = 1,
26462306a36Sopenharmony_ci		},
26562306a36Sopenharmony_ci		{
26662306a36Sopenharmony_ci			.rx_buf = sca_data->rxbuf,
26762306a36Sopenharmony_ci			.len = ARRAY_SIZE(sca_data->rxbuf),
26862306a36Sopenharmony_ci			.delay = delay,
26962306a36Sopenharmony_ci		}
27062306a36Sopenharmony_ci	};
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	/* inverted crc value as described in device data sheet */
27362306a36Sopenharmony_ci	crc = ~crc8(sca3300_crc_table, &sca_data->txbuf[0], 3, CRC8_INIT_VALUE);
27462306a36Sopenharmony_ci	sca_data->txbuf[3] = crc;
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	ret = spi_sync_transfer(sca_data->spi, xfers, ARRAY_SIZE(xfers));
27762306a36Sopenharmony_ci	if (ret) {
27862306a36Sopenharmony_ci		dev_err(&sca_data->spi->dev,
27962306a36Sopenharmony_ci			"transfer error, error: %d\n", ret);
28062306a36Sopenharmony_ci		return -EIO;
28162306a36Sopenharmony_ci	}
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	crc = ~crc8(sca3300_crc_table, &sca_data->rxbuf[0], 3, CRC8_INIT_VALUE);
28462306a36Sopenharmony_ci	if (sca_data->rxbuf[3] != crc) {
28562306a36Sopenharmony_ci		dev_err(&sca_data->spi->dev, "CRC checksum mismatch");
28662306a36Sopenharmony_ci		return -EIO;
28762306a36Sopenharmony_ci	}
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	/* get return status */
29062306a36Sopenharmony_ci	rs = sca_data->rxbuf[0] & SCA3300_MASK_RS_STATUS;
29162306a36Sopenharmony_ci	if (rs == SCA3300_VALUE_RS_ERROR)
29262306a36Sopenharmony_ci		ret = -EINVAL;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	*val = sign_extend32(get_unaligned_be16(&sca_data->rxbuf[1]), 15);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	return ret;
29762306a36Sopenharmony_ci}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic int sca3300_error_handler(struct sca3300_data *sca_data)
30062306a36Sopenharmony_ci{
30162306a36Sopenharmony_ci	int ret;
30262306a36Sopenharmony_ci	int val;
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	mutex_lock(&sca_data->lock);
30562306a36Sopenharmony_ci	sca_data->txbuf[0] = SCA3300_REG_STATUS << 2;
30662306a36Sopenharmony_ci	ret = sca3300_transfer(sca_data, &val);
30762306a36Sopenharmony_ci	mutex_unlock(&sca_data->lock);
30862306a36Sopenharmony_ci	/*
30962306a36Sopenharmony_ci	 * Return status error is cleared after reading status register once,
31062306a36Sopenharmony_ci	 * expect EINVAL here.
31162306a36Sopenharmony_ci	 */
31262306a36Sopenharmony_ci	if (ret != -EINVAL) {
31362306a36Sopenharmony_ci		dev_err(&sca_data->spi->dev,
31462306a36Sopenharmony_ci			"error reading device status: %d\n", ret);
31562306a36Sopenharmony_ci		return ret;
31662306a36Sopenharmony_ci	}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	dev_err(&sca_data->spi->dev, "device status: 0x%lx\n",
31962306a36Sopenharmony_ci		val & SCA3300_STATUS_MASK);
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	return 0;
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_cistatic int sca3300_read_reg(struct sca3300_data *sca_data, u8 reg, int *val)
32562306a36Sopenharmony_ci{
32662306a36Sopenharmony_ci	int ret;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	mutex_lock(&sca_data->lock);
32962306a36Sopenharmony_ci	sca_data->txbuf[0] = reg << 2;
33062306a36Sopenharmony_ci	ret = sca3300_transfer(sca_data, val);
33162306a36Sopenharmony_ci	mutex_unlock(&sca_data->lock);
33262306a36Sopenharmony_ci	if (ret != -EINVAL)
33362306a36Sopenharmony_ci		return ret;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	return sca3300_error_handler(sca_data);
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic int sca3300_write_reg(struct sca3300_data *sca_data, u8 reg, int val)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	int reg_val = 0;
34162306a36Sopenharmony_ci	int ret;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	mutex_lock(&sca_data->lock);
34462306a36Sopenharmony_ci	/* BIT(7) for write operation */
34562306a36Sopenharmony_ci	sca_data->txbuf[0] = BIT(7) | (reg << 2);
34662306a36Sopenharmony_ci	put_unaligned_be16(val, &sca_data->txbuf[1]);
34762306a36Sopenharmony_ci	ret = sca3300_transfer(sca_data, &reg_val);
34862306a36Sopenharmony_ci	mutex_unlock(&sca_data->lock);
34962306a36Sopenharmony_ci	if (ret != -EINVAL)
35062306a36Sopenharmony_ci		return ret;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	return sca3300_error_handler(sca_data);
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic int sca3300_set_op_mode(struct sca3300_data *sca_data, int index)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	if ((index < 0) || (index >= sca_data->chip->num_avail_modes))
35862306a36Sopenharmony_ci		return -EINVAL;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	return sca3300_write_reg(sca_data, SCA3300_REG_MODE,
36162306a36Sopenharmony_ci				 sca_data->chip->avail_modes_table[index]);
36262306a36Sopenharmony_ci}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_cistatic int sca3300_get_op_mode(struct sca3300_data *sca_data, int *index)
36562306a36Sopenharmony_ci{
36662306a36Sopenharmony_ci	int reg_val;
36762306a36Sopenharmony_ci	int ret;
36862306a36Sopenharmony_ci	int i;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	ret = sca3300_read_reg(sca_data, SCA3300_REG_MODE, &reg_val);
37162306a36Sopenharmony_ci	if (ret)
37262306a36Sopenharmony_ci		return ret;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	for (i = 0; i < sca_data->chip->num_avail_modes; i++) {
37562306a36Sopenharmony_ci		if (sca_data->chip->avail_modes_table[i] == reg_val)
37662306a36Sopenharmony_ci			break;
37762306a36Sopenharmony_ci	}
37862306a36Sopenharmony_ci	if (i == sca_data->chip->num_avail_modes)
37962306a36Sopenharmony_ci		return -EINVAL;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci	*index = i;
38262306a36Sopenharmony_ci	return 0;
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_cistatic int sca3300_set_frequency(struct sca3300_data *data, int val)
38662306a36Sopenharmony_ci{
38762306a36Sopenharmony_ci	const struct sca3300_chip_info *chip = data->chip;
38862306a36Sopenharmony_ci	unsigned int index;
38962306a36Sopenharmony_ci	int *opmode_scale;
39062306a36Sopenharmony_ci	int *new_scale;
39162306a36Sopenharmony_ci	unsigned int i;
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	if (sca3300_get_op_mode(data, &index))
39462306a36Sopenharmony_ci		return -EINVAL;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	/*
39762306a36Sopenharmony_ci	 * Find a mode in which the requested sampling frequency is available
39862306a36Sopenharmony_ci	 * and the scaling currently set is retained.
39962306a36Sopenharmony_ci	 */
40062306a36Sopenharmony_ci	opmode_scale = (int *)chip->accel_scale[chip->accel_scale_map[index]];
40162306a36Sopenharmony_ci	for (i = 0; i < chip->num_avail_modes; i++) {
40262306a36Sopenharmony_ci		new_scale = (int *)chip->accel_scale[chip->accel_scale_map[i]];
40362306a36Sopenharmony_ci		if ((val == chip->freq_table[chip->freq_map[i]]) &&
40462306a36Sopenharmony_ci		    (opmode_scale[1] == new_scale[1]) &&
40562306a36Sopenharmony_ci		    (opmode_scale[0] == new_scale[0]))
40662306a36Sopenharmony_ci			break;
40762306a36Sopenharmony_ci	}
40862306a36Sopenharmony_ci	if (i == chip->num_avail_modes)
40962306a36Sopenharmony_ci		return -EINVAL;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	return sca3300_set_op_mode(data, i);
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic int sca3300_write_raw(struct iio_dev *indio_dev,
41562306a36Sopenharmony_ci			     struct iio_chan_spec const *chan,
41662306a36Sopenharmony_ci			     int val, int val2, long mask)
41762306a36Sopenharmony_ci{
41862306a36Sopenharmony_ci	struct sca3300_data *data = iio_priv(indio_dev);
41962306a36Sopenharmony_ci	int index;
42062306a36Sopenharmony_ci	int i;
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	switch (mask) {
42362306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
42462306a36Sopenharmony_ci		if (chan->type != IIO_ACCEL)
42562306a36Sopenharmony_ci			return -EINVAL;
42662306a36Sopenharmony_ci		/*
42762306a36Sopenharmony_ci		 * Letting scale take priority over sampling frequency.
42862306a36Sopenharmony_ci		 * That makes sense given we can only ever end up increasing
42962306a36Sopenharmony_ci		 * the sampling frequency which is unlikely to be a problem.
43062306a36Sopenharmony_ci		 */
43162306a36Sopenharmony_ci		for (i = 0; i < data->chip->num_avail_modes; i++) {
43262306a36Sopenharmony_ci			index = data->chip->accel_scale_map[i];
43362306a36Sopenharmony_ci			if ((val  == data->chip->accel_scale[index][0]) &&
43462306a36Sopenharmony_ci			    (val2 == data->chip->accel_scale[index][1]))
43562306a36Sopenharmony_ci				return sca3300_set_op_mode(data, i);
43662306a36Sopenharmony_ci		}
43762306a36Sopenharmony_ci		return -EINVAL;
43862306a36Sopenharmony_ci	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
43962306a36Sopenharmony_ci		return sca3300_set_frequency(data, val);
44062306a36Sopenharmony_ci	default:
44162306a36Sopenharmony_ci		return -EINVAL;
44262306a36Sopenharmony_ci	}
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_cistatic int sca3300_read_raw(struct iio_dev *indio_dev,
44662306a36Sopenharmony_ci			    struct iio_chan_spec const *chan,
44762306a36Sopenharmony_ci			    int *val, int *val2, long mask)
44862306a36Sopenharmony_ci{
44962306a36Sopenharmony_ci	struct sca3300_data *data = iio_priv(indio_dev);
45062306a36Sopenharmony_ci	int index;
45162306a36Sopenharmony_ci	int ret;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	switch (mask) {
45462306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
45562306a36Sopenharmony_ci		ret = sca3300_read_reg(data, chan->address, val);
45662306a36Sopenharmony_ci		if (ret)
45762306a36Sopenharmony_ci			return ret;
45862306a36Sopenharmony_ci		return IIO_VAL_INT;
45962306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
46062306a36Sopenharmony_ci		ret = sca3300_get_op_mode(data, &index);
46162306a36Sopenharmony_ci		if (ret)
46262306a36Sopenharmony_ci			return ret;
46362306a36Sopenharmony_ci		switch (chan->type) {
46462306a36Sopenharmony_ci		case IIO_INCLI:
46562306a36Sopenharmony_ci			index = data->chip->incli_scale_map[index];
46662306a36Sopenharmony_ci			*val  = data->chip->incli_scale[index][0];
46762306a36Sopenharmony_ci			*val2 = data->chip->incli_scale[index][1];
46862306a36Sopenharmony_ci			return IIO_VAL_INT_PLUS_MICRO;
46962306a36Sopenharmony_ci		case IIO_ACCEL:
47062306a36Sopenharmony_ci			index = data->chip->accel_scale_map[index];
47162306a36Sopenharmony_ci			*val  = data->chip->accel_scale[index][0];
47262306a36Sopenharmony_ci			*val2 = data->chip->accel_scale[index][1];
47362306a36Sopenharmony_ci			return IIO_VAL_INT_PLUS_MICRO;
47462306a36Sopenharmony_ci		default:
47562306a36Sopenharmony_ci			return -EINVAL;
47662306a36Sopenharmony_ci		}
47762306a36Sopenharmony_ci	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
47862306a36Sopenharmony_ci		ret = sca3300_get_op_mode(data, &index);
47962306a36Sopenharmony_ci		if (ret)
48062306a36Sopenharmony_ci			return ret;
48162306a36Sopenharmony_ci		index = data->chip->freq_map[index];
48262306a36Sopenharmony_ci		*val = data->chip->freq_table[index];
48362306a36Sopenharmony_ci		return IIO_VAL_INT;
48462306a36Sopenharmony_ci	default:
48562306a36Sopenharmony_ci		return -EINVAL;
48662306a36Sopenharmony_ci	}
48762306a36Sopenharmony_ci}
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_cistatic irqreturn_t sca3300_trigger_handler(int irq, void *p)
49062306a36Sopenharmony_ci{
49162306a36Sopenharmony_ci	struct iio_poll_func *pf = p;
49262306a36Sopenharmony_ci	struct iio_dev *indio_dev = pf->indio_dev;
49362306a36Sopenharmony_ci	struct sca3300_data *data = iio_priv(indio_dev);
49462306a36Sopenharmony_ci	int bit, ret, val, i = 0;
49562306a36Sopenharmony_ci	s16 *channels = (s16 *)data->buffer;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	for_each_set_bit(bit, indio_dev->active_scan_mask,
49862306a36Sopenharmony_ci			 indio_dev->masklength) {
49962306a36Sopenharmony_ci		ret = sca3300_read_reg(data, indio_dev->channels[bit].address, &val);
50062306a36Sopenharmony_ci		if (ret) {
50162306a36Sopenharmony_ci			dev_err_ratelimited(&data->spi->dev,
50262306a36Sopenharmony_ci				"failed to read register, error: %d\n", ret);
50362306a36Sopenharmony_ci			/* handled, but bailing out due to errors */
50462306a36Sopenharmony_ci			goto out;
50562306a36Sopenharmony_ci		}
50662306a36Sopenharmony_ci		channels[i++] = val;
50762306a36Sopenharmony_ci	}
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
51062306a36Sopenharmony_ci					   iio_get_time_ns(indio_dev));
51162306a36Sopenharmony_ciout:
51262306a36Sopenharmony_ci	iio_trigger_notify_done(indio_dev->trig);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	return IRQ_HANDLED;
51562306a36Sopenharmony_ci}
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci/*
51862306a36Sopenharmony_ci * sca3300_init - Device init sequence. See datasheet rev 2 section
51962306a36Sopenharmony_ci * 4.2 Start-Up Sequence for details.
52062306a36Sopenharmony_ci */
52162306a36Sopenharmony_cistatic int sca3300_init(struct sca3300_data *sca_data,
52262306a36Sopenharmony_ci			struct iio_dev *indio_dev)
52362306a36Sopenharmony_ci{
52462306a36Sopenharmony_ci	int value = 0;
52562306a36Sopenharmony_ci	int ret;
52662306a36Sopenharmony_ci	int i;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	ret = sca3300_write_reg(sca_data, SCA3300_REG_MODE,
52962306a36Sopenharmony_ci				SCA3300_MODE_SW_RESET);
53062306a36Sopenharmony_ci	if (ret)
53162306a36Sopenharmony_ci		return ret;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	/*
53462306a36Sopenharmony_ci	 * Wait 1ms after SW-reset command.
53562306a36Sopenharmony_ci	 * Wait for the settling of signal paths,
53662306a36Sopenharmony_ci	 * 15ms for SCA3300 and 25ms for SCL3300,
53762306a36Sopenharmony_ci	 */
53862306a36Sopenharmony_ci	usleep_range(26e3, 50e3);
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	ret = sca3300_read_reg(sca_data, SCA3300_REG_WHOAMI, &value);
54162306a36Sopenharmony_ci	if (ret)
54262306a36Sopenharmony_ci		return ret;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(sca3300_chip_tbl); i++) {
54562306a36Sopenharmony_ci		if (sca3300_chip_tbl[i].chip_id == value)
54662306a36Sopenharmony_ci			break;
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci	if (i == ARRAY_SIZE(sca3300_chip_tbl)) {
54962306a36Sopenharmony_ci		dev_err(&sca_data->spi->dev, "unknown chip id %x\n", value);
55062306a36Sopenharmony_ci		return -ENODEV;
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	sca_data->chip = &sca3300_chip_tbl[i];
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	if (sca_data->chip->angle_supported) {
55662306a36Sopenharmony_ci		ret = sca3300_write_reg(sca_data, SCL3300_REG_ANG_CTRL,
55762306a36Sopenharmony_ci					SCL3300_ANG_ENABLE);
55862306a36Sopenharmony_ci		if (ret)
55962306a36Sopenharmony_ci			return ret;
56062306a36Sopenharmony_ci	}
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	return 0;
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_cistatic int sca3300_debugfs_reg_access(struct iio_dev *indio_dev,
56662306a36Sopenharmony_ci				      unsigned int reg, unsigned int writeval,
56762306a36Sopenharmony_ci				      unsigned int *readval)
56862306a36Sopenharmony_ci{
56962306a36Sopenharmony_ci	struct sca3300_data *data = iio_priv(indio_dev);
57062306a36Sopenharmony_ci	int value;
57162306a36Sopenharmony_ci	int ret;
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci	if (reg > SCA3300_REG_SELBANK)
57462306a36Sopenharmony_ci		return -EINVAL;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	if (!readval)
57762306a36Sopenharmony_ci		return sca3300_write_reg(data, reg, writeval);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	ret = sca3300_read_reg(data, reg, &value);
58062306a36Sopenharmony_ci	if (ret)
58162306a36Sopenharmony_ci		return ret;
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	*readval = value;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	return 0;
58662306a36Sopenharmony_ci}
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cistatic int sca3300_read_avail(struct iio_dev *indio_dev,
58962306a36Sopenharmony_ci			      struct iio_chan_spec const *chan,
59062306a36Sopenharmony_ci			      const int **vals, int *type, int *length,
59162306a36Sopenharmony_ci			      long mask)
59262306a36Sopenharmony_ci{
59362306a36Sopenharmony_ci	struct sca3300_data *data = iio_priv(indio_dev);
59462306a36Sopenharmony_ci	switch (mask) {
59562306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
59662306a36Sopenharmony_ci		switch (chan->type) {
59762306a36Sopenharmony_ci		case IIO_INCLI:
59862306a36Sopenharmony_ci			*vals = (const int *)data->chip->incli_scale;
59962306a36Sopenharmony_ci			*length = data->chip->num_incli_scales;
60062306a36Sopenharmony_ci			*type = IIO_VAL_INT_PLUS_MICRO;
60162306a36Sopenharmony_ci			return IIO_AVAIL_LIST;
60262306a36Sopenharmony_ci		case IIO_ACCEL:
60362306a36Sopenharmony_ci			*vals = (const int *)data->chip->accel_scale;
60462306a36Sopenharmony_ci			*length = data->chip->num_accel_scales;
60562306a36Sopenharmony_ci			*type = IIO_VAL_INT_PLUS_MICRO;
60662306a36Sopenharmony_ci			return IIO_AVAIL_LIST;
60762306a36Sopenharmony_ci		default:
60862306a36Sopenharmony_ci			return -EINVAL;
60962306a36Sopenharmony_ci		}
61062306a36Sopenharmony_ci	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
61162306a36Sopenharmony_ci		*vals = (const int *)data->chip->freq_table;
61262306a36Sopenharmony_ci		*length = data->chip->num_freqs;
61362306a36Sopenharmony_ci		*type = IIO_VAL_INT;
61462306a36Sopenharmony_ci		return IIO_AVAIL_LIST;
61562306a36Sopenharmony_ci	default:
61662306a36Sopenharmony_ci		return -EINVAL;
61762306a36Sopenharmony_ci	}
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_cistatic const struct iio_info sca3300_info = {
62162306a36Sopenharmony_ci	.read_raw = sca3300_read_raw,
62262306a36Sopenharmony_ci	.write_raw = sca3300_write_raw,
62362306a36Sopenharmony_ci	.debugfs_reg_access = &sca3300_debugfs_reg_access,
62462306a36Sopenharmony_ci	.read_avail = sca3300_read_avail,
62562306a36Sopenharmony_ci};
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_cistatic int sca3300_probe(struct spi_device *spi)
62862306a36Sopenharmony_ci{
62962306a36Sopenharmony_ci	struct sca3300_data *sca_data;
63062306a36Sopenharmony_ci	struct iio_dev *indio_dev;
63162306a36Sopenharmony_ci	int ret;
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*sca_data));
63462306a36Sopenharmony_ci	if (!indio_dev)
63562306a36Sopenharmony_ci		return -ENOMEM;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	sca_data = iio_priv(indio_dev);
63862306a36Sopenharmony_ci	mutex_init(&sca_data->lock);
63962306a36Sopenharmony_ci	sca_data->spi = spi;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	crc8_populate_msb(sca3300_crc_table, SCA3300_CRC8_POLYNOMIAL);
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	indio_dev->info = &sca3300_info;
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci	ret = sca3300_init(sca_data, indio_dev);
64662306a36Sopenharmony_ci	if (ret) {
64762306a36Sopenharmony_ci		dev_err(&spi->dev, "failed to init device, error: %d\n", ret);
64862306a36Sopenharmony_ci		return ret;
64962306a36Sopenharmony_ci	}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci	indio_dev->name = sca_data->chip->name;
65262306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
65362306a36Sopenharmony_ci	indio_dev->channels = sca_data->chip->channels;
65462306a36Sopenharmony_ci	indio_dev->num_channels = sca_data->chip->num_channels;
65562306a36Sopenharmony_ci	indio_dev->available_scan_masks = sca_data->chip->scan_masks;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
65862306a36Sopenharmony_ci					      iio_pollfunc_store_time,
65962306a36Sopenharmony_ci					      sca3300_trigger_handler, NULL);
66062306a36Sopenharmony_ci	if (ret) {
66162306a36Sopenharmony_ci		dev_err(&spi->dev,
66262306a36Sopenharmony_ci			"iio triggered buffer setup failed, error: %d\n", ret);
66362306a36Sopenharmony_ci		return ret;
66462306a36Sopenharmony_ci	}
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci	ret = devm_iio_device_register(&spi->dev, indio_dev);
66762306a36Sopenharmony_ci	if (ret) {
66862306a36Sopenharmony_ci		dev_err(&spi->dev, "iio device register failed, error: %d\n",
66962306a36Sopenharmony_ci			ret);
67062306a36Sopenharmony_ci	}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	return ret;
67362306a36Sopenharmony_ci}
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_cistatic const struct of_device_id sca3300_dt_ids[] = {
67662306a36Sopenharmony_ci	{ .compatible = "murata,sca3300"},
67762306a36Sopenharmony_ci	{ .compatible = "murata,scl3300"},
67862306a36Sopenharmony_ci	{}
67962306a36Sopenharmony_ci};
68062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, sca3300_dt_ids);
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_cistatic const struct spi_device_id sca3300_ids[] = {
68362306a36Sopenharmony_ci	{ "sca3300" },
68462306a36Sopenharmony_ci	{ "scl3300" },
68562306a36Sopenharmony_ci	{}
68662306a36Sopenharmony_ci};
68762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, sca3300_ids);
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_cistatic struct spi_driver sca3300_driver = {
69062306a36Sopenharmony_ci	.driver   = {
69162306a36Sopenharmony_ci		.name		= SCA3300_ALIAS,
69262306a36Sopenharmony_ci		.of_match_table = sca3300_dt_ids,
69362306a36Sopenharmony_ci	},
69462306a36Sopenharmony_ci	.probe	  = sca3300_probe,
69562306a36Sopenharmony_ci	.id_table = sca3300_ids,
69662306a36Sopenharmony_ci};
69762306a36Sopenharmony_cimodule_spi_driver(sca3300_driver);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ciMODULE_AUTHOR("Tomas Melin <tomas.melin@vaisala.com>");
70062306a36Sopenharmony_ciMODULE_DESCRIPTION("Murata SCA3300 SPI Accelerometer");
70162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
702