source: rtems/cpukit/dev/i2c/gpio-nxp-pca9535.c @ cfc53c1

4.115
Last change on this file since cfc53c1 was cfc53c1, checked in by Sebastian Huber <sebastian.huber@…>, on 11/24/14 at 10:55:44

i2c: Fix endian issue

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/**
2 * @file
3 *
4 * @brief GPIO NXP PCA9535 Driver Implementation
5 *
6 * @ingroup I2CGPIONXPPCA9535
7 */
8
9/*
10 * Copyright (c) 2014 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/gpio-nxp-pca9535.h>
28
29typedef enum {
30  GPIO_NXP_PCA9535_INPUT_PORT_0,
31  GPIO_NXP_PCA9535_INPUT_PORT_1,
32  GPIO_NXP_PCA9535_OUTPUT_PORT_0,
33  GPIO_NXP_PCA9535_OUTPUT_PORT_1,
34  GPIO_NXP_PCA9535_POL_INV_PORT_0,
35  GPIO_NXP_PCA9535_POL_INV_PORT_1,
36  GPIO_NXP_PCA9535_CONF_PORT_0,
37  GPIO_NXP_PCA9535_CONF_PORT_1
38} gpio_nxp_pca9535_port;
39
40static int gpio_nxp_pca9535_get_reg(
41  i2c_dev *dev,
42  gpio_nxp_pca9535_port port,
43  uint16_t *val
44)
45{
46  uint8_t out[1] = { port };
47  uint8_t in[sizeof(*val)];
48  i2c_msg msgs[2] = {
49    {
50      .addr = dev->address,
51      .flags = 0,
52      .len = (uint16_t) sizeof(out),
53      .buf = &out[0]
54    }, {
55      .addr = dev->address,
56      .flags = I2C_M_RD,
57      .len = (uint16_t) sizeof(in),
58      .buf = &in[0]
59    }
60  };
61  int err;
62
63  err = i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
64  *val = in[0] | (in[1] << 8);
65
66  return err;
67}
68
69static int gpio_nxp_pca9535_set_reg(
70  i2c_dev *dev,
71  gpio_nxp_pca9535_port port,
72  uint16_t val
73)
74{
75  uint8_t out[3] = { port, (uint8_t) val, (uint8_t) (val >> 8) };
76  i2c_msg msgs[1] = {
77    {
78      .addr = dev->address,
79      .flags = 0,
80      .len = (uint16_t) sizeof(out),
81      .buf = &out[0]
82    }
83  };
84
85  return i2c_bus_transfer(dev->bus, &msgs[0], RTEMS_ARRAY_SIZE(msgs));
86}
87
88static int gpio_nxp_pca9535_ioctl(
89  i2c_dev *dev,
90  ioctl_command_t command,
91  void *arg
92)
93{
94  uint16_t v16 = (uint16_t)(uintptr_t) arg;
95  uint32_t v32 = (uint32_t)(uintptr_t) arg;
96  int err;
97
98  switch (command) {
99    case GPIO_NXP_PCA9535_GET_INPUT:
100      err = gpio_nxp_pca9535_get_reg(dev, GPIO_NXP_PCA9535_INPUT_PORT_0, arg);
101      break;
102    case GPIO_NXP_PCA9535_GET_OUTPUT:
103      err = gpio_nxp_pca9535_get_reg(dev, GPIO_NXP_PCA9535_OUTPUT_PORT_0, arg);
104      break;
105    case GPIO_NXP_PCA9535_CLEAR_AND_SET_OUTPUT:
106      i2c_bus_obtain(dev->bus);
107      err = gpio_nxp_pca9535_get_reg(dev, GPIO_NXP_PCA9535_OUTPUT_PORT_0, &v16);
108      if (err == 0) {
109        v16 &= ~((uint16_t) v32);
110        v16 |= (uint16_t) (v32 >> 16);
111        err = gpio_nxp_pca9535_set_reg(dev, GPIO_NXP_PCA9535_OUTPUT_PORT_0, v16);
112      }
113      i2c_bus_release(dev->bus);
114      break;
115    case GPIO_NXP_PCA9535_SET_OUTPUT:
116      err = gpio_nxp_pca9535_set_reg(dev, GPIO_NXP_PCA9535_OUTPUT_PORT_0, v16);
117      break;
118    case GPIO_NXP_PCA9535_GET_POL_INV:
119      err = gpio_nxp_pca9535_get_reg(dev, GPIO_NXP_PCA9535_POL_INV_PORT_0, arg);
120      break;
121    case GPIO_NXP_PCA9535_SET_POL_INV:
122      err = gpio_nxp_pca9535_set_reg(dev, GPIO_NXP_PCA9535_POL_INV_PORT_0, v16);
123      break;
124    case GPIO_NXP_PCA9535_GET_CONFIG:
125      err = gpio_nxp_pca9535_get_reg(dev, GPIO_NXP_PCA9535_CONF_PORT_0, arg);
126      break;
127    case GPIO_NXP_PCA9535_SET_CONFIG:
128      err = gpio_nxp_pca9535_set_reg(dev, GPIO_NXP_PCA9535_CONF_PORT_0, v16);
129      break;
130    default:
131      err = -ENOTTY;
132      break;
133  }
134
135  return err;
136}
137
138int i2c_dev_register_gpio_nxp_pca9535(
139  const char *bus_path,
140  const char *dev_path,
141  uint16_t address
142)
143{
144  i2c_dev *dev;
145
146  dev = i2c_dev_alloc_and_init(sizeof(*dev), bus_path, address);
147  if (dev == NULL) {
148    return -1;
149  }
150
151  dev->ioctl = gpio_nxp_pca9535_ioctl;
152
153  return i2c_dev_register(dev, dev_path);
154}
Note: See TracBrowser for help on using the repository browser.