gpio_cdev/
ffi.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (c) 2018 The rust-gpio-cdev Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::IoctlKind;

pub const GPIOHANDLES_MAX: usize = 64;

// struct gpiochip_info
#[repr(C)]
pub struct gpiochip_info {
    pub name: [libc::c_char; 32],
    pub label: [libc::c_char; 32],
    pub lines: u32,
}

#[repr(C)]
pub struct gpioline_info {
    pub line_offset: u32,
    pub flags: u32,
    pub name: [libc::c_char; 32],
    pub consumer: [libc::c_char; 32],
}

#[repr(C)]
pub struct gpiohandle_request {
    pub lineoffsets: [u32; GPIOHANDLES_MAX],
    pub flags: u32,
    pub default_values: [u8; GPIOHANDLES_MAX],
    pub consumer_label: [libc::c_char; 32],
    pub lines: u32,
    pub fd: libc::c_int,
}

#[repr(C)]
pub struct gpiohandle_data {
    pub values: [u8; GPIOHANDLES_MAX],
}

#[repr(C)]
pub struct gpioevent_request {
    pub lineoffset: u32,
    pub handleflags: u32,
    pub eventflags: u32,
    pub consumer_label: [libc::c_char; 32],
    pub fd: libc::c_int,
}

#[repr(C)]
pub struct gpioevent_data {
    pub timestamp: u64,
    pub id: u32,
}

macro_rules! wrap_ioctl {
    ($ioctl_macro:ident!($name:ident, $ioty:expr, $nr:expr, $ty:ident), $ioctl_error_type:expr) => {
        mod $name {
            $ioctl_macro!($name, $ioty, $nr, super::$ty);
        }

        pub(crate) fn $name(fd: libc::c_int, data: &mut $ty) -> crate::errors::Result<libc::c_int> {
            unsafe {
                $name::$name(fd, data).map_err(|e| crate::errors::ioctl_err($ioctl_error_type, e))
            }
        }
    };
}

wrap_ioctl!(
    ioctl_read!(gpio_get_chipinfo_ioctl, 0xB4, 0x01, gpiochip_info),
    IoctlKind::ChipInfo
);
wrap_ioctl!(
    ioctl_readwrite!(gpio_get_lineinfo_ioctl, 0xB4, 0x02, gpioline_info),
    IoctlKind::LineInfo
);
wrap_ioctl!(
    ioctl_readwrite!(gpio_get_linehandle_ioctl, 0xB4, 0x03, gpiohandle_request),
    IoctlKind::LineHandle
);
wrap_ioctl!(
    ioctl_readwrite!(gpio_get_lineevent_ioctl, 0xB4, 0x04, gpioevent_request),
    IoctlKind::LineEvent
);

wrap_ioctl!(
    ioctl_readwrite!(
        gpiohandle_get_line_values_ioctl,
        0xB4,
        0x08,
        gpiohandle_data
    ),
    IoctlKind::GetLine
);
wrap_ioctl!(
    ioctl_readwrite!(
        gpiohandle_set_line_values_ioctl,
        0xB4,
        0x09,
        gpiohandle_data
    ),
    IoctlKind::SetLine
);