hc
2024-03-22 a0752693d998599af469473b8dc239ef973a012f
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
 * include/linux/spi/spidev.h
 *
 * Copyright (C) 2006 SWAPP
 *    Andrea Paterniani <a.paterniani@swapp-eng.it>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
#ifndef SPIDEV_H
#define SPIDEV_H
 
#include <linux/types.h>
#include <linux/ioctl.h>
 
/* User space versions of kernel symbols for SPI clocking modes,
 * matching <linux/spi/spi.h>
 */
 
#define SPI_CPHA        0x01
#define SPI_CPOL        0x02
 
#define SPI_MODE_0        (0|0)
#define SPI_MODE_1        (0|SPI_CPHA)
#define SPI_MODE_2        (SPI_CPOL|0)
#define SPI_MODE_3        (SPI_CPOL|SPI_CPHA)
 
#define SPI_CS_HIGH        0x04
#define SPI_LSB_FIRST        0x08
#define SPI_3WIRE        0x10
#define SPI_LOOP        0x20
#define SPI_NO_CS        0x40
#define SPI_READY        0x80
#define SPI_TX_DUAL        0x100
#define SPI_TX_QUAD        0x200
#define SPI_RX_DUAL        0x400
#define SPI_RX_QUAD        0x800
#define SPI_CS_WORD        0x1000
#define SPI_TX_OCTAL        0x2000
#define SPI_RX_OCTAL        0x4000
#define SPI_3WIRE_HIZ        0x8000
 
/*---------------------------------------------------------------------------*/
 
/* IOCTL commands */
 
#define SPI_IOC_MAGIC            'k'
 
/**
 * struct spi_ioc_transfer - describes a single SPI transfer
 * @tx_buf: Holds pointer to userspace buffer with transmit data, or null.
 *    If no data is provided, zeroes are shifted out.
 * @rx_buf: Holds pointer to userspace buffer for receive data, or null.
 * @len: Length of tx and rx buffers, in bytes.
 * @speed_hz: Temporary override of the device's bitrate.
 * @bits_per_word: Temporary override of the device's wordsize.
 * @delay_usecs: If nonzero, how long to delay after the last bit transfer
 *    before optionally deselecting the device before the next transfer.
 * @cs_change: True to deselect device before starting the next transfer.
 * @word_delay_usecs: If nonzero, how long to wait between words within one
 *    transfer. This property needs explicit support in the SPI controller,
 *    otherwise it is silently ignored.
 *
 * This structure is mapped directly to the kernel spi_transfer structure;
 * the fields have the same meanings, except of course that the pointers
 * are in a different address space (and may be of different sizes in some
 * cases, such as 32-bit i386 userspace over a 64-bit x86_64 kernel).
 * Zero-initialize the structure, including currently unused fields, to
 * accommodate potential future updates.
 *
 * SPI_IOC_MESSAGE gives userspace the equivalent of kernel spi_sync().
 * Pass it an array of related transfers, they'll execute together.
 * Each transfer may be half duplex (either direction) or full duplex.
 *
 *    struct spi_ioc_transfer mesg[4];
 *    ...
 *    status = ioctl(fd, SPI_IOC_MESSAGE(4), mesg);
 *
 * So for example one transfer might send a nine bit command (right aligned
 * in a 16-bit word), the next could read a block of 8-bit data before
 * terminating that command by temporarily deselecting the chip; the next
 * could send a different nine bit command (re-selecting the chip), and the
 * last transfer might write some register values.
 */
struct spi_ioc_transfer {
   __u64        tx_buf;
   __u64        rx_buf;
 
   __u32        len;
   __u32        speed_hz;
 
   __u16        delay_usecs;
   __u8        bits_per_word;
   __u8        cs_change;
   __u8        tx_nbits;
   __u8        rx_nbits;
   __u8        word_delay_usecs;
   __u8        pad;
 
   /* If the contents of 'struct spi_ioc_transfer' ever change
    * incompatibly, then the ioctl number (currently 0) must change;
    * ioctls with constant size fields get a bit more in the way of
    * error checking than ones (like this) where that field varies.
    *
    * NOTE: struct layout is the same in 64bit and 32bit userspace.
    */
};
 
/* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
#define SPI_MSGSIZE(N) \
   ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
       ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
#define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
 
 
/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) (limited to 8 bits) */
#define SPI_IOC_RD_MODE            _IOR(SPI_IOC_MAGIC, 1, __u8)
#define SPI_IOC_WR_MODE            _IOW(SPI_IOC_MAGIC, 1, __u8)
 
/* Read / Write SPI bit justification */
#define SPI_IOC_RD_LSB_FIRST        _IOR(SPI_IOC_MAGIC, 2, __u8)
#define SPI_IOC_WR_LSB_FIRST        _IOW(SPI_IOC_MAGIC, 2, __u8)
 
/* Read / Write SPI device word length (1..N) */
#define SPI_IOC_RD_BITS_PER_WORD    _IOR(SPI_IOC_MAGIC, 3, __u8)
#define SPI_IOC_WR_BITS_PER_WORD    _IOW(SPI_IOC_MAGIC, 3, __u8)
 
/* Read / Write SPI device default max speed hz */
#define SPI_IOC_RD_MAX_SPEED_HZ        _IOR(SPI_IOC_MAGIC, 4, __u32)
#define SPI_IOC_WR_MAX_SPEED_HZ        _IOW(SPI_IOC_MAGIC, 4, __u32)
 
/* Read / Write of the SPI mode field */
#define SPI_IOC_RD_MODE32        _IOR(SPI_IOC_MAGIC, 5, __u32)
#define SPI_IOC_WR_MODE32        _IOW(SPI_IOC_MAGIC, 5, __u32)
 
 
 
#endif /* SPIDEV_H */