1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2023, Linaro Ltd
5 */
6 #include <linux/auxiliary_bus.h>
7 #include <linux/module.h>
8 #include <linux/mutex.h>
9 #include <linux/property.h>
10 #include <linux/soc/qcom/pdr.h>
11 #include <linux/soc/qcom/pmic_glink.h>
12 #include "ucsi.h"
13
14 #define UCSI_BUF_SIZE 48
15
16 #define MSG_TYPE_REQ_RESP 1
17 #define UCSI_BUF_SIZE 48
18
19 #define UC_NOTIFY_RECEIVER_UCSI 0x0
20 #define UC_UCSI_READ_BUF_REQ 0x11
21 #define UC_UCSI_WRITE_BUF_REQ 0x12
22 #define UC_UCSI_USBC_NOTIFY_IND 0x13
23
24 struct ucsi_read_buf_req_msg {
25 struct pmic_glink_hdr hdr;
26 };
27
28 struct ucsi_read_buf_resp_msg {
29 struct pmic_glink_hdr hdr;
30 u8 buf[UCSI_BUF_SIZE];
31 u32 ret_code;
32 };
33
34 struct ucsi_write_buf_req_msg {
35 struct pmic_glink_hdr hdr;
36 u8 buf[UCSI_BUF_SIZE];
37 u32 reserved;
38 };
39
40 struct ucsi_write_buf_resp_msg {
41 struct pmic_glink_hdr hdr;
42 u32 ret_code;
43 };
44
45 struct ucsi_notify_ind_msg {
46 struct pmic_glink_hdr hdr;
47 u32 notification;
48 u32 receiver;
49 u32 reserved;
50 };
51
52 struct pmic_glink_ucsi {
53 struct device *dev;
54
55 struct pmic_glink_client *client;
56
57 struct ucsi *ucsi;
58 struct completion read_ack;
59 struct completion write_ack;
60 struct completion sync_ack;
61 bool sync_pending;
62 struct mutex lock; /* protects concurrent access to PMIC Glink interface */
63
64 int sync_val;
65
66 struct work_struct notify_work;
67 struct work_struct register_work;
68
69 u8 read_buf[UCSI_BUF_SIZE];
70 };
71
pmic_glink_ucsi_read(struct ucsi * __ucsi,unsigned int offset,void * val,size_t val_len)72 static int pmic_glink_ucsi_read(struct ucsi *__ucsi, unsigned int offset,
73 void *val, size_t val_len)
74 {
75 struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
76 struct ucsi_read_buf_req_msg req = {};
77 unsigned long left;
78 int ret;
79
80 req.hdr.owner = PMIC_GLINK_OWNER_USBC;
81 req.hdr.type = MSG_TYPE_REQ_RESP;
82 req.hdr.opcode = UC_UCSI_READ_BUF_REQ;
83
84 mutex_lock(&ucsi->lock);
85 memset(ucsi->read_buf, 0, sizeof(ucsi->read_buf));
86 reinit_completion(&ucsi->read_ack);
87
88 ret = pmic_glink_send(ucsi->client, &req, sizeof(req));
89 if (ret < 0) {
90 dev_err(ucsi->dev, "failed to send UCSI read request: %d\n", ret);
91 goto out_unlock;
92 }
93
94 left = wait_for_completion_timeout(&ucsi->read_ack, 5 * HZ);
95 if (!left) {
96 dev_err(ucsi->dev, "timeout waiting for UCSI read response\n");
97 ret = -ETIMEDOUT;
98 goto out_unlock;
99 }
100
101 memcpy(val, &ucsi->read_buf[offset], val_len);
102 ret = 0;
103
104 out_unlock:
105 mutex_unlock(&ucsi->lock);
106
107 return ret;
108 }
109
pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi * ucsi,unsigned int offset,const void * val,size_t val_len)110 static int pmic_glink_ucsi_locked_write(struct pmic_glink_ucsi *ucsi, unsigned int offset,
111 const void *val, size_t val_len)
112 {
113 struct ucsi_write_buf_req_msg req = {};
114 unsigned long left;
115 int ret;
116
117 req.hdr.owner = PMIC_GLINK_OWNER_USBC;
118 req.hdr.type = MSG_TYPE_REQ_RESP;
119 req.hdr.opcode = UC_UCSI_WRITE_BUF_REQ;
120 memcpy(&req.buf[offset], val, val_len);
121
122 reinit_completion(&ucsi->write_ack);
123
124 ret = pmic_glink_send(ucsi->client, &req, sizeof(req));
125 if (ret < 0) {
126 dev_err(ucsi->dev, "failed to send UCSI write request: %d\n", ret);
127 return ret;
128 }
129
130 left = wait_for_completion_timeout(&ucsi->write_ack, 5 * HZ);
131 if (!left) {
132 dev_err(ucsi->dev, "timeout waiting for UCSI write response\n");
133 return -ETIMEDOUT;
134 }
135
136 return 0;
137 }
138
pmic_glink_ucsi_async_write(struct ucsi * __ucsi,unsigned int offset,const void * val,size_t val_len)139 static int pmic_glink_ucsi_async_write(struct ucsi *__ucsi, unsigned int offset,
140 const void *val, size_t val_len)
141 {
142 struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
143 int ret;
144
145 mutex_lock(&ucsi->lock);
146 ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len);
147 mutex_unlock(&ucsi->lock);
148
149 return ret;
150 }
151
pmic_glink_ucsi_sync_write(struct ucsi * __ucsi,unsigned int offset,const void * val,size_t val_len)152 static int pmic_glink_ucsi_sync_write(struct ucsi *__ucsi, unsigned int offset,
153 const void *val, size_t val_len)
154 {
155 struct pmic_glink_ucsi *ucsi = ucsi_get_drvdata(__ucsi);
156 unsigned long left;
157 int ret;
158
159 /* TOFIX: Downstream forces recipient to CON when UCSI_GET_ALTERNATE_MODES command */
160
161 mutex_lock(&ucsi->lock);
162 ucsi->sync_val = 0;
163 reinit_completion(&ucsi->sync_ack);
164 ucsi->sync_pending = true;
165 ret = pmic_glink_ucsi_locked_write(ucsi, offset, val, val_len);
166 mutex_unlock(&ucsi->lock);
167
168 left = wait_for_completion_timeout(&ucsi->sync_ack, 5 * HZ);
169 if (!left) {
170 dev_err(ucsi->dev, "timeout waiting for UCSI sync write response\n");
171 ret = -ETIMEDOUT;
172 } else if (ucsi->sync_val) {
173 dev_err(ucsi->dev, "sync write returned: %d\n", ucsi->sync_val);
174 }
175
176 ucsi->sync_pending = false;
177
178 return ret;
179 }
180
181 static const struct ucsi_operations pmic_glink_ucsi_ops = {
182 .read = pmic_glink_ucsi_read,
183 .sync_write = pmic_glink_ucsi_sync_write,
184 .async_write = pmic_glink_ucsi_async_write
185 };
186
pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi * ucsi,const void * data,int len)187 static void pmic_glink_ucsi_read_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len)
188 {
189 const struct ucsi_read_buf_resp_msg *resp = data;
190
191 if (resp->ret_code)
192 return;
193
194 memcpy(ucsi->read_buf, resp->buf, UCSI_BUF_SIZE);
195 complete(&ucsi->read_ack);
196 }
197
pmic_glink_ucsi_write_ack(struct pmic_glink_ucsi * ucsi,const void * data,int len)198 static void pmic_glink_ucsi_write_ack(struct pmic_glink_ucsi *ucsi, const void *data, int len)
199 {
200 const struct ucsi_write_buf_resp_msg *resp = data;
201
202 if (resp->ret_code)
203 return;
204
205 ucsi->sync_val = resp->ret_code;
206 complete(&ucsi->write_ack);
207 }
208
pmic_glink_ucsi_notify(struct work_struct * work)209 static void pmic_glink_ucsi_notify(struct work_struct *work)
210 {
211 struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, notify_work);
212 unsigned int con_num;
213 u32 cci;
214 int ret;
215
216 ret = pmic_glink_ucsi_read(ucsi->ucsi, UCSI_CCI, &cci, sizeof(cci));
217 if (ret) {
218 dev_err(ucsi->dev, "failed to read CCI on notification\n");
219 return;
220 }
221
222 con_num = UCSI_CCI_CONNECTOR(cci);
223 if (con_num)
224 ucsi_connector_change(ucsi->ucsi, con_num);
225
226 if (ucsi->sync_pending && cci & UCSI_CCI_BUSY) {
227 ucsi->sync_val = -EBUSY;
228 complete(&ucsi->sync_ack);
229 } else if (ucsi->sync_pending &&
230 (cci & (UCSI_CCI_ACK_COMPLETE | UCSI_CCI_COMMAND_COMPLETE))) {
231 complete(&ucsi->sync_ack);
232 }
233 }
234
pmic_glink_ucsi_register(struct work_struct * work)235 static void pmic_glink_ucsi_register(struct work_struct *work)
236 {
237 struct pmic_glink_ucsi *ucsi = container_of(work, struct pmic_glink_ucsi, register_work);
238
239 ucsi_register(ucsi->ucsi);
240 }
241
pmic_glink_ucsi_callback(const void * data,size_t len,void * priv)242 static void pmic_glink_ucsi_callback(const void *data, size_t len, void *priv)
243 {
244 struct pmic_glink_ucsi *ucsi = priv;
245 const struct pmic_glink_hdr *hdr = data;
246
247 switch (le32_to_cpu(hdr->opcode)) {
248 case UC_UCSI_READ_BUF_REQ:
249 pmic_glink_ucsi_read_ack(ucsi, data, len);
250 break;
251 case UC_UCSI_WRITE_BUF_REQ:
252 pmic_glink_ucsi_write_ack(ucsi, data, len);
253 break;
254 case UC_UCSI_USBC_NOTIFY_IND:
255 schedule_work(&ucsi->notify_work);
256 break;
257 };
258 }
259
pmic_glink_ucsi_pdr_notify(void * priv,int state)260 static void pmic_glink_ucsi_pdr_notify(void *priv, int state)
261 {
262 struct pmic_glink_ucsi *ucsi = priv;
263
264 if (state == SERVREG_SERVICE_STATE_UP)
265 schedule_work(&ucsi->register_work);
266 else if (state == SERVREG_SERVICE_STATE_DOWN)
267 ucsi_unregister(ucsi->ucsi);
268 }
269
pmic_glink_ucsi_destroy(void * data)270 static void pmic_glink_ucsi_destroy(void *data)
271 {
272 struct pmic_glink_ucsi *ucsi = data;
273
274 /* Protect to make sure we're not in a middle of a transaction from a glink callback */
275 mutex_lock(&ucsi->lock);
276 ucsi_destroy(ucsi->ucsi);
277 mutex_unlock(&ucsi->lock);
278 }
279
pmic_glink_ucsi_probe(struct auxiliary_device * adev,const struct auxiliary_device_id * id)280 static int pmic_glink_ucsi_probe(struct auxiliary_device *adev,
281 const struct auxiliary_device_id *id)
282 {
283 struct pmic_glink_ucsi *ucsi;
284 struct device *dev = &adev->dev;
285 int ret;
286
287 ucsi = devm_kzalloc(dev, sizeof(*ucsi), GFP_KERNEL);
288 if (!ucsi)
289 return -ENOMEM;
290
291 ucsi->dev = dev;
292 dev_set_drvdata(dev, ucsi);
293
294 INIT_WORK(&ucsi->notify_work, pmic_glink_ucsi_notify);
295 INIT_WORK(&ucsi->register_work, pmic_glink_ucsi_register);
296 init_completion(&ucsi->read_ack);
297 init_completion(&ucsi->write_ack);
298 init_completion(&ucsi->sync_ack);
299 mutex_init(&ucsi->lock);
300
301 ucsi->ucsi = ucsi_create(dev, &pmic_glink_ucsi_ops);
302 if (IS_ERR(ucsi->ucsi))
303 return PTR_ERR(ucsi->ucsi);
304
305 /* Make sure we destroy *after* pmic_glink unregister */
306 ret = devm_add_action_or_reset(dev, pmic_glink_ucsi_destroy, ucsi);
307 if (ret)
308 return ret;
309
310 ucsi_set_drvdata(ucsi->ucsi, ucsi);
311
312 ucsi->client = devm_pmic_glink_register_client(dev,
313 PMIC_GLINK_OWNER_USBC,
314 pmic_glink_ucsi_callback,
315 pmic_glink_ucsi_pdr_notify,
316 ucsi);
317 return PTR_ERR_OR_ZERO(ucsi->client);
318 }
319
pmic_glink_ucsi_remove(struct auxiliary_device * adev)320 static void pmic_glink_ucsi_remove(struct auxiliary_device *adev)
321 {
322 struct pmic_glink_ucsi *ucsi = dev_get_drvdata(&adev->dev);
323
324 /* Unregister first to stop having read & writes */
325 ucsi_unregister(ucsi->ucsi);
326 }
327
328 static const struct auxiliary_device_id pmic_glink_ucsi_id_table[] = {
329 { .name = "pmic_glink.ucsi", },
330 {},
331 };
332 MODULE_DEVICE_TABLE(auxiliary, pmic_glink_ucsi_id_table);
333
334 static struct auxiliary_driver pmic_glink_ucsi_driver = {
335 .name = "pmic_glink_ucsi",
336 .probe = pmic_glink_ucsi_probe,
337 .remove = pmic_glink_ucsi_remove,
338 .id_table = pmic_glink_ucsi_id_table,
339 };
340
341 module_auxiliary_driver(pmic_glink_ucsi_driver);
342
343 MODULE_DESCRIPTION("Qualcomm PMIC GLINK UCSI driver");
344 MODULE_LICENSE("GPL");
345