hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-License-Identifier: GPL-2.0-only
/*
 * SPI interface for the BMP280 driver
 *
 * Inspired by the older BMP085 driver drivers/misc/bmp085-spi.c
 */
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/err.h>
#include <linux/regmap.h>
 
#include "bmp280.h"
 
static int bmp280_regmap_spi_write(void *context, const void *data,
                                   size_t count)
{
   struct device *dev = context;
   struct spi_device *spi = to_spi_device(dev);
   u8 buf[2];
 
   memcpy(buf, data, 2);
   /*
    * The SPI register address (= full register address without bit 7) and
    * the write command (bit7 = RW = '0')
    */
   buf[0] &= ~0x80;
 
   return spi_write_then_read(spi, buf, 2, NULL, 0);
}
 
static int bmp280_regmap_spi_read(void *context, const void *reg,
                                  size_t reg_size, void *val, size_t val_size)
{
   struct device *dev = context;
   struct spi_device *spi = to_spi_device(dev);
 
   return spi_write_then_read(spi, reg, reg_size, val, val_size);
}
 
static struct regmap_bus bmp280_regmap_bus = {
   .write = bmp280_regmap_spi_write,
   .read = bmp280_regmap_spi_read,
   .reg_format_endian_default = REGMAP_ENDIAN_BIG,
   .val_format_endian_default = REGMAP_ENDIAN_BIG,
};
 
static int bmp280_spi_probe(struct spi_device *spi)
{
   const struct spi_device_id *id = spi_get_device_id(spi);
   struct regmap *regmap;
   const struct regmap_config *regmap_config;
   int ret;
 
   spi->bits_per_word = 8;
   ret = spi_setup(spi);
   if (ret < 0) {
       dev_err(&spi->dev, "spi_setup failed!\n");
       return ret;
   }
 
   switch (id->driver_data) {
   case BMP180_CHIP_ID:
       regmap_config = &bmp180_regmap_config;
       break;
   case BMP280_CHIP_ID:
   case BME280_CHIP_ID:
       regmap_config = &bmp280_regmap_config;
       break;
   default:
       return -EINVAL;
   }
 
   regmap = devm_regmap_init(&spi->dev,
                 &bmp280_regmap_bus,
                 &spi->dev,
                 regmap_config);
   if (IS_ERR(regmap)) {
       dev_err(&spi->dev, "failed to allocate register map\n");
       return PTR_ERR(regmap);
   }
 
   return bmp280_common_probe(&spi->dev,
                  regmap,
                  id->driver_data,
                  id->name,
                  spi->irq);
}
 
static const struct of_device_id bmp280_of_spi_match[] = {
   { .compatible = "bosch,bmp085", },
   { .compatible = "bosch,bmp180", },
   { .compatible = "bosch,bmp181", },
   { .compatible = "bosch,bmp280", },
   { .compatible = "bosch,bme280", },
   { },
};
MODULE_DEVICE_TABLE(of, bmp280_of_spi_match);
 
static const struct spi_device_id bmp280_spi_id[] = {
   { "bmp180", BMP180_CHIP_ID },
   { "bmp181", BMP180_CHIP_ID },
   { "bmp280", BMP280_CHIP_ID },
   { "bme280", BME280_CHIP_ID },
   { }
};
MODULE_DEVICE_TABLE(spi, bmp280_spi_id);
 
static struct spi_driver bmp280_spi_driver = {
   .driver = {
       .name = "bmp280",
       .of_match_table = bmp280_of_spi_match,
       .pm = &bmp280_dev_pm_ops,
   },
   .id_table = bmp280_spi_id,
   .probe = bmp280_spi_probe,
};
module_spi_driver(bmp280_spi_driver);
 
MODULE_DESCRIPTION("BMP280 SPI bus driver");
MODULE_LICENSE("GPL");