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

ms5611_i2c.c (3228B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * MS5611 pressure and temperature sensor driver (I2C bus)
      4 *
      5 * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
      6 *
      7 * 7-bit I2C slave addresses:
      8 *
      9 * 0x77 (CSB pin low)
     10 * 0x76 (CSB pin high)
     11 *
     12 */
     13
     14#include <linux/delay.h>
     15#include <linux/i2c.h>
     16#include <linux/module.h>
     17#include <linux/mod_devicetable.h>
     18
     19#include <asm/unaligned.h>
     20
     21#include "ms5611.h"
     22
     23static int ms5611_i2c_reset(struct ms5611_state *st)
     24{
     25	return i2c_smbus_write_byte(st->client, MS5611_RESET);
     26}
     27
     28static int ms5611_i2c_read_prom_word(struct ms5611_state *st, int index,
     29				     u16 *word)
     30{
     31	int ret;
     32
     33	ret = i2c_smbus_read_word_swapped(st->client,
     34			MS5611_READ_PROM_WORD + (index << 1));
     35	if (ret < 0)
     36		return ret;
     37
     38	*word = ret;
     39
     40	return 0;
     41}
     42
     43static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val)
     44{
     45	int ret;
     46	u8 buf[3];
     47
     48	ret = i2c_smbus_read_i2c_block_data(st->client, MS5611_READ_ADC,
     49					    3, buf);
     50	if (ret < 0)
     51		return ret;
     52
     53	*val = get_unaligned_be24(&buf[0]);
     54
     55	return 0;
     56}
     57
     58static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st,
     59						 s32 *temp, s32 *pressure)
     60{
     61	int ret;
     62	const struct ms5611_osr *osr = st->temp_osr;
     63
     64	ret = i2c_smbus_write_byte(st->client, osr->cmd);
     65	if (ret < 0)
     66		return ret;
     67
     68	usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
     69	ret = ms5611_i2c_read_adc(st, temp);
     70	if (ret < 0)
     71		return ret;
     72
     73	osr = st->pressure_osr;
     74	ret = i2c_smbus_write_byte(st->client, osr->cmd);
     75	if (ret < 0)
     76		return ret;
     77
     78	usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL));
     79	return ms5611_i2c_read_adc(st, pressure);
     80}
     81
     82static int ms5611_i2c_probe(struct i2c_client *client,
     83			    const struct i2c_device_id *id)
     84{
     85	struct ms5611_state *st;
     86	struct iio_dev *indio_dev;
     87
     88	if (!i2c_check_functionality(client->adapter,
     89				     I2C_FUNC_SMBUS_WRITE_BYTE |
     90				     I2C_FUNC_SMBUS_READ_WORD_DATA |
     91				     I2C_FUNC_SMBUS_READ_I2C_BLOCK))
     92		return -EOPNOTSUPP;
     93
     94	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
     95	if (!indio_dev)
     96		return -ENOMEM;
     97
     98	st = iio_priv(indio_dev);
     99	i2c_set_clientdata(client, indio_dev);
    100	st->reset = ms5611_i2c_reset;
    101	st->read_prom_word = ms5611_i2c_read_prom_word;
    102	st->read_adc_temp_and_pressure = ms5611_i2c_read_adc_temp_and_pressure;
    103	st->client = client;
    104
    105	return ms5611_probe(indio_dev, &client->dev, id->name, id->driver_data);
    106}
    107
    108static int ms5611_i2c_remove(struct i2c_client *client)
    109{
    110	ms5611_remove(i2c_get_clientdata(client));
    111
    112	return 0;
    113}
    114
    115static const struct of_device_id ms5611_i2c_matches[] = {
    116	{ .compatible = "meas,ms5611" },
    117	{ .compatible = "meas,ms5607" },
    118	{ }
    119};
    120MODULE_DEVICE_TABLE(of, ms5611_i2c_matches);
    121
    122static const struct i2c_device_id ms5611_id[] = {
    123	{ "ms5611", MS5611 },
    124	{ "ms5607", MS5607 },
    125	{ }
    126};
    127MODULE_DEVICE_TABLE(i2c, ms5611_id);
    128
    129static struct i2c_driver ms5611_driver = {
    130	.driver = {
    131		.name = "ms5611",
    132		.of_match_table = ms5611_i2c_matches,
    133	},
    134	.id_table = ms5611_id,
    135	.probe = ms5611_i2c_probe,
    136	.remove = ms5611_i2c_remove,
    137};
    138module_i2c_driver(ms5611_driver);
    139
    140MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
    141MODULE_DESCRIPTION("MS5611 i2c driver");
    142MODULE_LICENSE("GPL v2");
    143MODULE_IMPORT_NS(IIO_MS5611);