diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-tegra-hv-common.h')
-rw-r--r-- | drivers/i2c/busses/i2c-tegra-hv-common.h | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/i2c/busses/i2c-tegra-hv-common.h b/drivers/i2c/busses/i2c-tegra-hv-common.h new file mode 100644 index 000000000..b41f822c1 --- /dev/null +++ b/drivers/i2c/busses/i2c-tegra-hv-common.h | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef __I2C_LIB_HV_H__ | ||
15 | #define __I2C_LIB_HV_H__ | ||
16 | |||
17 | #ifdef CONFIG_TEGRA_HV_MANAGER | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/tegra-ivc.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/workqueue.h> | ||
23 | |||
24 | typedef void (*i2c_isr_handler)(void *context); | ||
25 | |||
26 | struct tegra_hv_i2c_comm_chan; | ||
27 | |||
28 | int hv_i2c_transfer(struct tegra_hv_i2c_comm_chan *comm_chan, int cont_id, | ||
29 | int addr, int read, uint8_t *buf, size_t len, int *err, | ||
30 | int seq_no, bool more_msgs); | ||
31 | int hv_i2c_get_max_payload(struct tegra_hv_i2c_comm_chan *comm_chan, | ||
32 | int cont_id, uint32_t *max_payload, int *err); | ||
33 | int hv_i2c_comm_chan_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan, | ||
34 | int cont_id); | ||
35 | void hv_i2c_comm_chan_free(struct tegra_hv_i2c_comm_chan *comm_chan); | ||
36 | void *hv_i2c_comm_init(struct device *dev, i2c_isr_handler handler, | ||
37 | void *data); | ||
38 | |||
39 | #define MAX_COMM_CHANS 7 | ||
40 | #define COMM_CHAN_UNASSIGNED MAX_COMM_CHANS | ||
41 | |||
42 | enum i2c_ivc_msg_t { | ||
43 | I2C_READ, | ||
44 | I2C_READ_RESPONSE, | ||
45 | I2C_WRITE, | ||
46 | I2C_WRITE_RESPONSE, | ||
47 | I2C_GET_MAX_PAYLOAD, | ||
48 | I2C_GET_MAX_PAYLOAD_RESPONSE, | ||
49 | I2C_CLEANUP, | ||
50 | I2C_CLEANUP_RESPONSE, | ||
51 | I2C_INVALID, | ||
52 | }; | ||
53 | |||
54 | enum i2c_rx_state_t { | ||
55 | I2C_RX_INIT, | ||
56 | I2C_RX_PENDING, | ||
57 | I2C_RX_PENDING_CLEANUP, | ||
58 | }; | ||
59 | |||
60 | #define HV_I2C_FLAGS_REPEAT_START (1<<0) | ||
61 | |||
62 | struct i2c_ivc_msg_common { | ||
63 | uint32_t s_marker; | ||
64 | uint32_t msg_type; | ||
65 | int32_t comm_chan_id; | ||
66 | uint32_t controller_instance; | ||
67 | uint32_t err; | ||
68 | uint32_t e_marker; | ||
69 | }; | ||
70 | |||
71 | struct i2c_ivc_msg_tx_rx_hdr { | ||
72 | int32_t seq_no; | ||
73 | uint32_t slave_address; | ||
74 | uint32_t slave_reg; | ||
75 | uint32_t buf_len; | ||
76 | uint32_t flags; | ||
77 | }; | ||
78 | |||
79 | struct i2c_ivc_msg_tx_rx { | ||
80 | struct i2c_ivc_msg_tx_rx_hdr fixed; | ||
81 | uint8_t buffer[4096]; | ||
82 | }; | ||
83 | |||
84 | struct i2c_ivc_msg_max_payload { | ||
85 | uint32_t max_payload; | ||
86 | }; | ||
87 | |||
88 | struct i2c_ivc_msg { | ||
89 | struct i2c_ivc_msg_common hdr; | ||
90 | union { | ||
91 | struct i2c_ivc_msg_tx_rx m; | ||
92 | struct i2c_ivc_msg_max_payload p; | ||
93 | } body; | ||
94 | }; | ||
95 | |||
96 | #define I2C_IVC_COMMON_HEADER_LEN sizeof(struct i2c_ivc_msg_common) | ||
97 | |||
98 | #define i2c_ivc_start_marker(_msg_ptr) (_msg_ptr->hdr.s_marker) | ||
99 | #define i2c_ivc_end_marker(_msg_ptr) (_msg_ptr->hdr.e_marker) | ||
100 | #define i2c_ivc_chan_id(_msg_ptr) (_msg_ptr->hdr.comm_chan_id) | ||
101 | #define i2c_ivc_controller_instance(_msg_ptr) \ | ||
102 | (_msg_ptr->hdr.controller_instance) | ||
103 | #define i2c_ivc_msg_type(_msg_ptr) (_msg_ptr->hdr.msg_type) | ||
104 | #define i2c_ivc_error_field(_msg_ptr) (_msg_ptr->hdr.err) | ||
105 | |||
106 | #define i2c_ivc_message_seq_nr(_msg_ptr) \ | ||
107 | (_msg_ptr->body.m.fixed.seq_no) | ||
108 | #define i2c_ivc_message_slave_addr(_msg_ptr) \ | ||
109 | (_msg_ptr->body.m.fixed.slave_address) | ||
110 | #define i2c_ivc_message_slave_reg(_msg_ptr) \ | ||
111 | (_msg_ptr->body.m.fixed.slave_reg) | ||
112 | #define i2c_ivc_message_buf_len(_msg_ptr) \ | ||
113 | (_msg_ptr->body.m.fixed.buf_len) | ||
114 | #define i2c_ivc_message_flags(_msg_ptr) (_msg_ptr->body.m.fixed.flags) | ||
115 | #define i2c_ivc_message_buffer(_msg_ptr) \ | ||
116 | (_msg_ptr->body.m.buffer[0]) | ||
117 | |||
118 | #define i2c_ivc_max_payload_field(_msg_ptr) \ | ||
119 | (_msg_ptr->body.p.max_payload) | ||
120 | |||
121 | struct tegra_hv_i2c_comm_dev; | ||
122 | |||
123 | /* channel is virtual abstraction over a single ivc queue | ||
124 | * each channel holds messages that are independent of other channels | ||
125 | * we allocate one channel per i2c adapter as these can operate in parallel | ||
126 | */ | ||
127 | struct tegra_hv_i2c_comm_chan { | ||
128 | struct tegra_hv_ivc_cookie *ivck; | ||
129 | struct device *dev; | ||
130 | int id; | ||
131 | i2c_isr_handler handler; | ||
132 | void *data; | ||
133 | void *rcvd_data; | ||
134 | size_t data_len; | ||
135 | int *rcvd_err; | ||
136 | enum i2c_rx_state_t rx_state; | ||
137 | struct tegra_hv_i2c_comm_dev *hv_comm_dev; | ||
138 | spinlock_t lock; | ||
139 | }; | ||
140 | |||
141 | |||
142 | struct tegra_hv_i2c_comm_dev { | ||
143 | uint32_t queue_id; | ||
144 | struct tegra_hv_ivc_cookie *ivck; | ||
145 | spinlock_t ivck_tx_lock; | ||
146 | spinlock_t lock; | ||
147 | struct hlist_node list; | ||
148 | struct work_struct work; | ||
149 | struct tegra_hv_i2c_comm_chan *hv_comm_chan[MAX_COMM_CHANS]; | ||
150 | }; | ||
151 | #endif | ||
152 | #endif | ||