Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:11

0001 /**
0002  * @file
0003  *
0004  * @brief Temperature Sensor LM75A Driver Implementation
0005  *
0006  * @ingroup I2CSensorLM75A
0007  */
0008 
0009 /*
0010  * Copyright (c) 2017 embedded brains GmbH & Co. KG
0011  *
0012  * The license and distribution terms for this file may be
0013  * found in the file LICENSE in this distribution or at
0014  * http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020 
0021 #include <dev/i2c/sensor-lm75a.h>
0022 
0023 typedef enum {
0024   SENSOR_LM75A_PTR_TEMP,
0025   SENSOR_LM75A_PTR_CONF,
0026   SENSOR_LM75A_PTR_THYST,
0027   SENSOR_LM75A_PTR_TOS
0028 } sensor_lm75a_ptr;
0029 
0030 static int sensor_lm75a_get_reg_8(
0031   i2c_dev *dev,
0032   sensor_lm75a_ptr ptr,
0033   uint8_t *val
0034 )
0035 {
0036   uint8_t out[1] = { ptr };
0037   uint8_t in[sizeof(*val)];
0038   i2c_msg msgs[2] = {
0039     {
0040       .addr = dev->address,
0041       .flags = 0,
0042       .len = (uint16_t) sizeof(out),
0043       .buf = &out[0]
0044     }, {
0045       .addr = dev->address,
0046       .flags = I2C_M_RD,
0047       .len = (uint16_t) sizeof(in),
0048       .buf = &in[0]
0049     }
0050   };
0051   int err;
0052 
0053   err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
0054   *val = in[0];
0055 
0056   return err;
0057 }
0058 
0059 static int sensor_lm75a_set_reg_8(
0060   i2c_dev *dev,
0061   sensor_lm75a_ptr ptr,
0062   uint8_t val
0063 )
0064 {
0065   uint8_t out[2] = { ptr, val };
0066   i2c_msg msgs[1] = {
0067     {
0068       .addr = dev->address,
0069       .flags = 0,
0070       .len = (uint16_t) sizeof(out),
0071       .buf = &out[0]
0072     }
0073   };
0074 
0075   return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
0076 }
0077 
0078 static int sensor_lm75a_get_reg_16(
0079   i2c_dev *dev,
0080   sensor_lm75a_ptr ptr,
0081   uint16_t *val
0082 )
0083 {
0084   uint8_t out[1] = { ptr };
0085   uint8_t in[sizeof(*val)];
0086   i2c_msg msgs[2] = {
0087     {
0088       .addr = dev->address,
0089       .flags = 0,
0090       .len = (uint16_t) sizeof(out),
0091       .buf = &out[0]
0092     }, {
0093       .addr = dev->address,
0094       .flags = I2C_M_RD,
0095       .len = (uint16_t) sizeof(in),
0096       .buf = &in[0]
0097     }
0098   };
0099   int err;
0100 
0101   err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
0102   *val = (in[0] << 8) | in[1];
0103 
0104   return err;
0105 }
0106 
0107 static int sensor_lm75a_set_reg_16(
0108   i2c_dev *dev,
0109   sensor_lm75a_ptr ptr,
0110   uint16_t val
0111 )
0112 {
0113   uint8_t out[3] = { ptr, (uint8_t) (val >> 8), (uint8_t) val };
0114   i2c_msg msgs[1] = {
0115     {
0116       .addr = dev->address,
0117       .flags = 0,
0118       .len = (uint16_t) sizeof(out),
0119       .buf = &out[0]
0120     }
0121   };
0122 
0123   return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
0124 }
0125 
0126 static int sensor_lm75a_ioctl(
0127   i2c_dev *dev,
0128   ioctl_command_t command,
0129   void *arg
0130 )
0131 {
0132   uint8_t v8 = (uint8_t) (uintptr_t) arg;
0133   uint16_t v16 = (uint16_t) (uintptr_t) arg;
0134   int err;
0135 
0136   switch (command) {
0137     case SENSOR_LM75A_GET_CONF:
0138       err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, arg);
0139       break;
0140     case SENSOR_LM75A_SET_CONF:
0141       err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
0142       break;
0143     case SENSOR_LM75A_CLEAR_AND_SET_CONF:
0144       i2c_bus_obtain(dev->bus);
0145       err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, &v8);
0146       if (err == 0) {
0147         v8 &= ~((uint8_t) v16);
0148         v8 |= (uint8_t) (v16 >> 8);
0149         err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
0150       }
0151       i2c_bus_release(dev->bus);
0152       break;
0153     case SENSOR_LM75A_GET_TEMP:
0154       err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TEMP, arg);
0155       break;
0156     case SENSOR_LM75A_GET_TOS:
0157       err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TOS, arg);
0158       break;
0159     case SENSOR_LM75A_SET_TOS:
0160       err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_TOS, v16);
0161       break;
0162     case SENSOR_LM75A_GET_THYST:
0163       err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_THYST, arg);
0164       break;
0165     case SENSOR_LM75A_SET_THYST:
0166       err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_THYST, v16);
0167       break;
0168     default:
0169       err = -ENOTTY;
0170       break;
0171   }
0172 
0173   return err;
0174 }
0175 
0176 int i2c_dev_register_sensor_lm75a(
0177   const char *bus_path,
0178   const char *dev_path,
0179   uint16_t address
0180 )
0181 {
0182   i2c_dev *dev;
0183 
0184   dev = i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
0185   if (dev == NULL) {
0186     return -1;
0187   }
0188 
0189   dev->ioctl = sensor_lm75a_ioctl;
0190 
0191   return i2c_dev_register(dev, dev_path);
0192 }