source: rtems/cpukit/dev/i2c/sensor-lm75a.c @ 05015dc1

5
Last change on this file since 05015dc1 was 4cfce5c, checked in by Sebastian Huber <sebastian.huber@…>, on 09/28/17 at 06:13:01

i2c: Add temperature sensor LM75A driver

Close #3163.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Temperature Sensor LM75A Driver Implementation
5 *
6 * @ingroup I2CSensorLM75A
7 */
8
9/*
10 * Copyright (c) 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#if HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <dev/i2c/sensor-lm75a.h>
28
29typedef enum {
30  SENSOR_LM75A_PTR_TEMP,
31  SENSOR_LM75A_PTR_CONF,
32  SENSOR_LM75A_PTR_THYST,
33  SENSOR_LM75A_PTR_TOS
34} sensor_lm75a_ptr;
35
36static int sensor_lm75a_get_reg_8(
37  i2c_dev *dev,
38  sensor_lm75a_ptr ptr,
39  uint8_t *val
40)
41{
42  uint8_t out[1] = { ptr };
43  uint8_t in[sizeof(*val)];
44  i2c_msg msgs[2] = {
45    {
46      .addr = dev->address,
47      .flags = 0,
48      .len = (uint16_t) sizeof(out),
49      .buf = &out[0]
50    }, {
51      .addr = dev->address,
52      .flags = I2C_M_RD,
53      .len = (uint16_t) sizeof(in),
54      .buf = &in[0]
55    }
56  };
57  int err;
58
59  err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
60  *val = in[0];
61
62  return err;
63}
64
65static int sensor_lm75a_set_reg_8(
66  i2c_dev *dev,
67  sensor_lm75a_ptr ptr,
68  uint8_t val
69)
70{
71  uint8_t out[2] = { ptr, val };
72  i2c_msg msgs[1] = {
73    {
74      .addr = dev->address,
75      .flags = 0,
76      .len = (uint16_t) sizeof(out),
77      .buf = &out[0]
78    }
79  };
80
81  return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
82}
83
84static int sensor_lm75a_get_reg_16(
85  i2c_dev *dev,
86  sensor_lm75a_ptr ptr,
87  uint16_t *val
88)
89{
90  uint8_t out[1] = { ptr };
91  uint8_t in[sizeof(*val)];
92  i2c_msg msgs[2] = {
93    {
94      .addr = dev->address,
95      .flags = 0,
96      .len = (uint16_t) sizeof(out),
97      .buf = &out[0]
98    }, {
99      .addr = dev->address,
100      .flags = I2C_M_RD,
101      .len = (uint16_t) sizeof(in),
102      .buf = &in[0]
103    }
104  };
105  int err;
106
107  err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
108  *val = (in[0] << 8) | in[1];
109
110  return err;
111}
112
113static int sensor_lm75a_set_reg_16(
114  i2c_dev *dev,
115  sensor_lm75a_ptr ptr,
116  uint16_t val
117)
118{
119  uint8_t out[3] = { ptr, (uint8_t) (val >> 8), (uint8_t) val };
120  i2c_msg msgs[1] = {
121    {
122      .addr = dev->address,
123      .flags = 0,
124      .len = (uint16_t) sizeof(out),
125      .buf = &out[0]
126    }
127  };
128
129  return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
130}
131
132static int sensor_lm75a_ioctl(
133  i2c_dev *dev,
134  ioctl_command_t command,
135  void *arg
136)
137{
138  uint8_t v8 = (uint8_t) (uintptr_t) arg;
139  uint16_t v16 = (uint16_t) (uintptr_t) arg;
140  int err;
141
142  switch (command) {
143    case SENSOR_LM75A_GET_CONF:
144      err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, arg);
145      break;
146    case SENSOR_LM75A_SET_CONF:
147      err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
148      break;
149    case SENSOR_LM75A_CLEAR_AND_SET_CONF:
150      i2c_bus_obtain(dev->bus);
151      err = sensor_lm75a_get_reg_8(dev, SENSOR_LM75A_PTR_CONF, &v8);
152      if (err == 0) {
153        v8 &= ~((uint8_t) v16);
154        v8 |= (uint8_t) (v16 >> 8);
155        err = sensor_lm75a_set_reg_8(dev, SENSOR_LM75A_PTR_CONF, v8);
156      }
157      i2c_bus_release(dev->bus);
158      break;
159    case SENSOR_LM75A_GET_TEMP:
160      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TEMP, arg);
161      break;
162    case SENSOR_LM75A_GET_TOS:
163      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_TOS, arg);
164      break;
165    case SENSOR_LM75A_SET_TOS:
166      err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_TOS, v16);
167      break;
168    case SENSOR_LM75A_GET_THYST:
169      err = sensor_lm75a_get_reg_16(dev, SENSOR_LM75A_PTR_THYST, arg);
170      break;
171    case SENSOR_LM75A_SET_THYST:
172      err = sensor_lm75a_set_reg_16(dev, SENSOR_LM75A_PTR_THYST, v16);
173      break;
174    default:
175      err = -ENOTTY;
176      break;
177  }
178
179  return err;
180}
181
182int i2c_dev_register_sensor_lm75a(
183  const char *bus_path,
184  const char *dev_path,
185  uint16_t address
186)
187{
188  i2c_dev *dev;
189
190  dev = i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
191  if (dev == NULL) {
192    return -1;
193  }
194
195  dev->ioctl = sensor_lm75a_ioctl;
196
197  return i2c_dev_register(dev, dev_path);
198}
Note: See TracBrowser for help on using the repository browser.