1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * SPI interface for the BMP280 driver
4 *
5 * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c
6 */
7#include <linux/bits.h>
8#include <linux/module.h>
9#include <linux/spi/spi.h>
10#include <linux/err.h>
11#include <linux/regmap.h>
12
13#include "bmp280.h"
14
15static int bmp280_regmap_spi_write(void *context, const void *data,
16                                   size_t count)
17{
18	struct spi_device *spi = to_spi_device(context);
19	u8 buf[2];
20
21	memcpy(buf, data, 2);
22	/*
23	 * The SPI register address (= full register address without bit 7) and
24	 * the write command (bit7 = RW = '0')
25	 */
26	buf[0] &= ~0x80;
27
28	return spi_write_then_read(spi, buf, 2, NULL, 0);
29}
30
31static int bmp280_regmap_spi_read(void *context, const void *reg,
32                                  size_t reg_size, void *val, size_t val_size)
33{
34	struct spi_device *spi = to_spi_device(context);
35
36	return spi_write_then_read(spi, reg, reg_size, val, val_size);
37}
38
39static int bmp380_regmap_spi_read(void *context, const void *reg,
40				  size_t reg_size, void *val, size_t val_size)
41{
42	struct spi_device *spi = to_spi_device(context);
43	u8 rx_buf[4];
44	ssize_t status;
45
46	/*
47	 * Maximum number of consecutive bytes read for a temperature or
48	 * pressure measurement is 3.
49	 */
50	if (val_size > 3)
51		return -EINVAL;
52
53	/*
54	 * According to the BMP3xx datasheets, for a basic SPI read opertion,
55	 * the first byte needs to be dropped and the rest are the requested
56	 * data.
57	 */
58	status = spi_write_then_read(spi, reg, 1, rx_buf, val_size + 1);
59	if (status)
60		return status;
61
62	memcpy(val, rx_buf + 1, val_size);
63
64	return 0;
65}
66
67static struct regmap_bus bmp280_regmap_bus = {
68	.write = bmp280_regmap_spi_write,
69	.read = bmp280_regmap_spi_read,
70	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
71	.val_format_endian_default = REGMAP_ENDIAN_BIG,
72};
73
74static struct regmap_bus bmp380_regmap_bus = {
75	.write = bmp280_regmap_spi_write,
76	.read = bmp380_regmap_spi_read,
77	.read_flag_mask = BIT(7),
78	.reg_format_endian_default = REGMAP_ENDIAN_BIG,
79	.val_format_endian_default = REGMAP_ENDIAN_BIG,
80};
81
82static int bmp280_spi_probe(struct spi_device *spi)
83{
84	const struct spi_device_id *id = spi_get_device_id(spi);
85	const struct bmp280_chip_info *chip_info;
86	struct regmap_bus *bmp_regmap_bus;
87	struct regmap *regmap;
88	int ret;
89
90	spi->bits_per_word = 8;
91	ret = spi_setup(spi);
92	if (ret < 0) {
93		dev_err(&spi->dev, "spi_setup failed!\n");
94		return ret;
95	}
96
97	chip_info = spi_get_device_match_data(spi);
98
99	switch (chip_info->chip_id[0]) {
100	case BMP380_CHIP_ID:
101	case BMP390_CHIP_ID:
102		bmp_regmap_bus = &bmp380_regmap_bus;
103		break;
104	default:
105		bmp_regmap_bus = &bmp280_regmap_bus;
106		break;
107	}
108
109	regmap = devm_regmap_init(&spi->dev,
110				  bmp_regmap_bus,
111				  &spi->dev,
112				  chip_info->regmap_config);
113	if (IS_ERR(regmap)) {
114		dev_err(&spi->dev, "failed to allocate register map\n");
115		return PTR_ERR(regmap);
116	}
117
118	return bmp280_common_probe(&spi->dev,
119				   regmap,
120				   chip_info,
121				   id->name,
122				   spi->irq);
123}
124
125static const struct of_device_id bmp280_of_spi_match[] = {
126	{ .compatible = "bosch,bmp085", .data = &bmp180_chip_info },
127	{ .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
128	{ .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
129	{ .compatible = "bosch,bmp280", .data = &bmp280_chip_info },
130	{ .compatible = "bosch,bme280", .data = &bmp280_chip_info },
131	{ .compatible = "bosch,bmp380", .data = &bmp380_chip_info },
132	{ .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
133	{ },
134};
135MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
136
137static const struct spi_device_id bmp280_spi_id[] = {
138	{ "bmp085", (kernel_ulong_t)&bmp180_chip_info },
139	{ "bmp180", (kernel_ulong_t)&bmp180_chip_info },
140	{ "bmp181", (kernel_ulong_t)&bmp180_chip_info },
141	{ "bmp280", (kernel_ulong_t)&bmp280_chip_info },
142	{ "bme280", (kernel_ulong_t)&bmp280_chip_info },
143	{ "bmp380", (kernel_ulong_t)&bmp380_chip_info },
144	{ "bmp580", (kernel_ulong_t)&bmp580_chip_info },
145	{ }
146};
147MODULE_DEVICE_TABLE(spi, bmp280_spi_id);
148
149static struct spi_driver bmp280_spi_driver = {
150	.driver = {
151		.name = "bmp280",
152		.of_match_table = bmp280_of_spi_match,
153		.pm = pm_ptr(&bmp280_dev_pm_ops),
154	},
155	.id_table = bmp280_spi_id,
156	.probe = bmp280_spi_probe,
157};
158module_spi_driver(bmp280_spi_driver);
159
160MODULE_DESCRIPTION("BMP280 SPI bus driver");
161MODULE_LICENSE("GPL");
162MODULE_IMPORT_NS(IIO_BMP280);
163