flinklib
flinklib: flink C library for Linux
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
base.c
Go to the documentation of this file.
1 /*******************************************************************
2  * _________ _____ _____ ____ _____ ___ ____ *
3  * |_ ___ | |_ _| |_ _| |_ \|_ _| |_ ||_ _| *
4  * | |_ \_| | | | | | \ | | | |_/ / *
5  * | _| | | _ | | | |\ \| | | __'. *
6  * _| |_ _| |__/ | _| |_ _| |_\ |_ _| | \ \_ *
7  * |_____| |________| |_____| |_____|\____| |____||____| *
8  * *
9  *******************************************************************
10  * *
11  * fLink userspace library, base functionality *
12  * *
13  *******************************************************************/
14 
25 #include "flinklib.h"
26 #include "flinkioctl.h"
27 #include "types.h"
28 #include "valid.h"
29 #include "error.h"
30 #include "log.h"
31 
32 #include <stdlib.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 
36 
37 /*******************************************************************
38  * *
39  * Internal (private) methods *
40  * *
41  *******************************************************************/
42 
49 static int read_nof_subdevices(flink_dev* dev) {
50  uint8_t n = 0;
51 
52  dbg_print("reading number of subdevices...\n");
53 
54  if(flink_ioctl(dev, READ_NOF_SUBDEVICES, &n) < 0) {
55  dbg_print(" --> failed!\n");
56  libc_error();
57  return EXIT_ERROR;
58  }
59  dbg_print(" --> %u\n", n);
60  return n;
61 }
62 
69 static int get_subdevices(flink_dev* dev) {
70  flink_subdev* subdev = NULL;
71  int i = 0, ret = 0;
72 
73  if(!validate_flink_dev(dev)) {
75  return EXIT_ERROR;
76  }
77 
78  // Read nof subdevices
79  dev->nof_subdevices = read_nof_subdevices(dev);
80 
81  // Allocate memory
82  dev->subdevices = calloc(dev->nof_subdevices, sizeof(flink_subdev));
83  if(dev->subdevices == NULL) { // allocation failed
84  libc_error();
85  dev->nof_subdevices = 0;
86  return EXIT_ERROR;
87  }
88 
89  // Fillup all information
90  for(i = 0; i < dev->nof_subdevices; i++) { // for each subdevice
91  subdev = dev->subdevices + i;
92  subdev->id = i;
93  ret = flink_ioctl(dev, READ_SUBDEVICE_INFO, subdev);
94  subdev->parent = dev;
95  }
96 
97  return ret;
98 }
99 
100 
101 /*******************************************************************
102  * *
103  * Public methods *
104  * *
105  *******************************************************************/
106 
112 flink_dev* flink_open(const char* file_name) {
113  flink_dev* dev = NULL;
114 
115  // Allocate memory for flink_t
116  dev = malloc(sizeof(flink_dev));
117  if(dev == NULL) { // allocation failed
118  libc_error();
119  return NULL;
120  }
121 
122  // Open device file
123  dev->fd = open(file_name, O_RDWR);
124  if(dev->fd < 0) { // failed to open device
125  free(dev);
126  libc_error();
127  return NULL;
128  }
129 
130  if(get_subdevices(dev) < 0) { // reading subdevices failed
131  close(dev->fd);
132  free(dev);
133  return NULL;
134  }
135 
136  return dev;
137 }
138 
139 
146  flink_subdev* subdev = NULL;
147  int i = 0;
148 
149  if(!validate_flink_dev(dev)) {
151  return EXIT_ERROR;
152  }
153 
154  if(dev->subdevices) {
155  free(dev->subdevices);
156  }
157 
158  close(dev->fd);
159  free(dev);
160  return EXIT_SUCCESS;
161 }
162 
163 
170 
171  if(!validate_flink_dev(dev)) {
173  return EXIT_ERROR;
174  }
175 
176  return dev->nof_subdevices;
177 }
178 
179 
186  uint32_t offset = CONFIG_OFFSET;
187  uint8_t reset = 1;
188 
189  if(!validate_flink_subdev(subdev)) {
191  return EXIT_ERROR;
192  }
193 
194  if(flink_write_bit(subdev, offset, RESET_BIT, &reset)) {
195  libc_error();
196  return EXIT_ERROR;
197  }
198  return EXIT_SUCCESS;
199 }
200 
201 
208 int flink_subdevice_select(flink_subdev* subdev, uint8_t exclusive) {
210  if(exclusive) cmd = SELECT_SUBDEVICE_EXCL;
211 
212  if(flink_ioctl(subdev->parent, cmd, &(subdev->id)) < 0) {
213  libc_error();
214  return EXIT_ERROR;
215  }
216  return EXIT_SUCCESS;
217 }
218 
226 
227  // Check flink device structure
228  if(!validate_flink_dev(dev)) {
230  return NULL;
231  }
232 
233  // Check subdevice id
234  if(subdev_id > dev->nof_subdevices) {
236  return NULL;
237  }
238 
239  return dev->subdevices + subdev_id;
240 }
241 
249  flink_subdev* subdev = dev->subdevices;
250 
251  // Check flink device structure
252  if(!validate_flink_dev(dev)) {
254  return NULL;
255  }
256 
257  while(subdev != NULL) {
258  if(subdev->unique_id == unique_id) {
259  return dev->subdevices;
260  }
261  subdev = subdev + 1;
262  }
263  return NULL;
264 }
265 
272  return subdev->id;
273 }
274 
281  return subdev->function_id;
282 }
283 
290  return subdev->sub_function_id;
291 }
292 
299  return subdev->function_version;
300 }
301 
308  return subdev->base_addr;
309 }
310 
317  return subdev->mem_size;
318 }
319 
326  return subdev->nof_channels;
327 }
328 
335  return subdev->unique_id;
336 }
flink_subdev * flink_get_subdevice_by_id(flink_dev *dev, uint8_t subdev_id)
Find subdevice of a device with a given id.
Definition: base.c:225
Data structures for flink devices and subdevices.
ioctl_cmd_t
Definition: flinkioctl.h:26
flink_subdev * flink_get_subdevice_by_unique_id(flink_dev *dev, uint8_t unique_id)
Find subdevice of a device with a given unique id.
Definition: base.c:248
flink_dev * flink_open(const char *file_name)
Opens a flink device file.
Definition: base.c:112
int flink_close(flink_dev *dev)
Close an open flink device.
Definition: base.c:145
int flink_subdevice_select(flink_subdev *subdev, uint8_t exclusive)
Select a flink subdevice for further operations.
Definition: base.c:208
uint32_t flink_subdevice_get_nofchannels(flink_subdev *subdev)
Get the number of channels of a subdevice.
Definition: base.c:325
#define FLINK_EINVALDEV
Definition: error.h:29
#define EXIT_ERROR
Definition: flinklib.h:118
uint8_t flink_subdevice_get_id(flink_subdev *subdev)
Get the id of a subdevice.
Definition: base.c:271
Error handling.
uint8_t flink_subdevice_get_subfunction(flink_subdev *subdev)
Get the subfunction of a subdevice.
Definition: base.c:289
#define CONFIG_OFFSET
Definition: flinklib.h:52
uint16_t flink_subdevice_get_function(flink_subdev *subdev)
Get the function of a subdevice.
Definition: base.c:280
uint8_t flink_subdevice_get_function_version(flink_subdev *subdev)
Get the function version of a subdevice.
Definition: base.c:298
flink userspace library, ioctl definitions.
int flink_write_bit(flink_subdev *subdev, uint32_t offset, uint8_t bit, void *wdata)
Write a single bit to a flink subdevice.
Definition: lowlevel.c:189
#define EXIT_SUCCESS
Definition: flinklib.h:117
int flink_ioctl(flink_dev *dev, int cmd, void *arg)
IOCTL operation for a flink device.
Definition: lowlevel.c:44
int validate_flink_subdev(flink_subdev *subdev)
Checks if flink subdevice belongs to the device.
Definition: valid.c:40
#define FLINK_EINVALSUBDEV
Definition: error.h:30
Contains validation functions for flink.
int flink_subdevice_reset(flink_subdev *subdev)
Reset a flink subdevice.
Definition: base.c:185
uint32_t flink_subdevice_get_unique_id(flink_subdev *subdev)
Get the unique id of a subdevice.
Definition: base.c:334
#define RESET_BIT
Definition: flinklib.h:59
void flink_error(int e)
Definition: error.c:64
uint32_t flink_subdevice_get_memsize(flink_subdev *subdev)
Get the memory size of a subdevice.
Definition: base.c:316
int validate_flink_dev(flink_dev *dev)
Checks if flink device was opened.
Definition: valid.c:28
void libc_error(void)
Definition: error.c:56
int flink_get_nof_subdevices(flink_dev *dev)
Returns the number of subdevices of a fink device.
Definition: base.c:169
Debug utilities.
uint32_t flink_subdevice_get_baseaddr(flink_subdev *subdev)
Get the base address of a subdevice.
Definition: base.c:307
#define dbg_print(fmt,...)
Definition: log.h:29