1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
4  * Copyright (c) 2022, Linaro Ltd
5  */
6 #include <linux/auxiliary_bus.h>
7 #include <linux/bitfield.h>
8 #include <linux/module.h>
9 #include <linux/of_device.h>
10 #include <linux/mutex.h>
11 #include <linux/property.h>
12 #include <linux/soc/qcom/pdr.h>
13 #include <drm/drm_bridge.h>
14 
15 #include <linux/usb/typec_altmode.h>
16 #include <linux/usb/typec_dp.h>
17 #include <linux/usb/typec_mux.h>
18 
19 #include <linux/soc/qcom/pmic_glink.h>
20 
21 #define PMIC_GLINK_MAX_PORTS	2
22 
23 #define USBC_SC8180X_NOTIFY_IND	0x13
24 #define USBC_CMD_WRITE_REQ      0x15
25 #define USBC_NOTIFY_IND		0x16
26 
27 #define ALTMODE_PAN_EN		0x10
28 #define ALTMODE_PAN_ACK		0x11
29 
30 struct usbc_write_req {
31 	struct pmic_glink_hdr   hdr;
32 	__le32 cmd;
33 	__le32 arg;
34 	__le32 reserved;
35 };
36 
37 #define NOTIFY_PAYLOAD_SIZE 16
38 struct usbc_notify {
39 	struct pmic_glink_hdr hdr;
40 	char payload[NOTIFY_PAYLOAD_SIZE];
41 	u32 reserved;
42 };
43 
44 struct usbc_sc8180x_notify {
45 	struct pmic_glink_hdr hdr;
46 	__le32 notification;
47 	__le32 reserved[2];
48 };
49 
50 enum pmic_glink_altmode_pin_assignment {
51 	DPAM_HPD_OUT,
52 	DPAM_HPD_A,
53 	DPAM_HPD_B,
54 	DPAM_HPD_C,
55 	DPAM_HPD_D,
56 	DPAM_HPD_E,
57 	DPAM_HPD_F,
58 };
59 
60 struct pmic_glink_altmode;
61 
62 #define work_to_altmode_port(w) container_of((w), struct pmic_glink_altmode_port, work)
63 
64 struct pmic_glink_altmode_port {
65 	struct pmic_glink_altmode *altmode;
66 	unsigned int index;
67 
68 	struct typec_switch *typec_switch;
69 	struct typec_mux *typec_mux;
70 	struct typec_mux_state state;
71 	struct typec_altmode dp_alt;
72 
73 	struct work_struct work;
74 
75 	struct drm_bridge bridge;
76 
77 	enum typec_orientation orientation;
78 	u16 svid;
79 	u8 dp_data;
80 	u8 mode;
81 	u8 hpd_state;
82 	u8 hpd_irq;
83 };
84 
85 #define work_to_altmode(w) container_of((w), struct pmic_glink_altmode, enable_work)
86 
87 struct pmic_glink_altmode {
88 	struct device *dev;
89 
90 	unsigned int owner_id;
91 
92 	/* To synchronize WRITE_REQ acks */
93 	struct mutex lock;
94 
95 	struct completion pan_ack;
96 	struct pmic_glink_client *client;
97 
98 	struct work_struct enable_work;
99 
100 	struct pmic_glink_altmode_port ports[PMIC_GLINK_MAX_PORTS];
101 };
102 
103 static int pmic_glink_altmode_request(struct pmic_glink_altmode *altmode, u32 cmd, u32 arg)
104 {
105 	struct usbc_write_req req = {};
106 	unsigned long left;
107 	int ret;
108 
109 	/*
110 	 * The USBC_CMD_WRITE_REQ ack doesn't identify the request, so wait for
111 	 * one ack at a time.
112 	 */
113 	mutex_lock(&altmode->lock);
114 
115 	req.hdr.owner = cpu_to_le32(altmode->owner_id);
116 	req.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP);
117 	req.hdr.opcode = cpu_to_le32(USBC_CMD_WRITE_REQ);
118 	req.cmd = cpu_to_le32(cmd);
119 	req.arg = cpu_to_le32(arg);
120 
121 	ret = pmic_glink_send(altmode->client, &req, sizeof(req));
122 	if (ret) {
123 		dev_err(altmode->dev, "failed to send altmode request: %#x (%d)\n", cmd, ret);
124 		goto out_unlock;
125 	}
126 
127 	left = wait_for_completion_timeout(&altmode->pan_ack, 5 * HZ);
128 	if (!left) {
129 		dev_err(altmode->dev, "timeout waiting for altmode request ack for: %#x\n", cmd);
130 		ret = -ETIMEDOUT;
131 	}
132 
133 out_unlock:
134 	mutex_unlock(&altmode->lock);
135 	return ret;
136 }
137 
138 static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode,
139 					 struct pmic_glink_altmode_port *port,
140 					 u8 mode, bool hpd_state,
141 					 bool hpd_irq)
142 {
143 	struct typec_displayport_data dp_data = {};
144 	int ret;
145 
146 	dp_data.status = DP_STATUS_ENABLED;
147 	if (hpd_state)
148 		dp_data.status |= DP_STATUS_HPD_STATE;
149 	if (hpd_irq)
150 		dp_data.status |= DP_STATUS_IRQ_HPD;
151 	dp_data.conf = DP_CONF_SET_PIN_ASSIGN(mode);
152 
153 	port->state.alt = &port->dp_alt;
154 	port->state.data = &dp_data;
155 	port->state.mode = TYPEC_MODAL_STATE(mode);
156 
157 	ret = typec_mux_set(port->typec_mux, &port->state);
158 	if (ret)
159 		dev_err(altmode->dev, "failed to switch mux to DP\n");
160 }
161 
162 static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode,
163 					  struct pmic_glink_altmode_port *port)
164 {
165 	int ret;
166 
167 	port->state.alt = NULL;
168 	port->state.data = NULL;
169 	port->state.mode = TYPEC_STATE_USB;
170 
171 	ret = typec_mux_set(port->typec_mux, &port->state);
172 	if (ret)
173 		dev_err(altmode->dev, "failed to switch mux to USB\n");
174 }
175 
176 static void pmic_glink_altmode_worker(struct work_struct *work)
177 {
178 	struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work);
179 	struct pmic_glink_altmode *altmode = alt_port->altmode;
180 
181 	typec_switch_set(alt_port->typec_switch, alt_port->orientation);
182 
183 	if (alt_port->svid == USB_TYPEC_DP_SID)
184 		pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode,
185 					     alt_port->hpd_state, alt_port->hpd_irq);
186 	else
187 		pmic_glink_altmode_enable_usb(altmode, alt_port);
188 
189 	if (alt_port->hpd_state)
190 		drm_bridge_hpd_notify(&alt_port->bridge, connector_status_connected);
191 	else
192 		drm_bridge_hpd_notify(&alt_port->bridge, connector_status_disconnected);
193 
194 	pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index);
195 };
196 
197 static enum typec_orientation pmic_glink_altmode_orientation(unsigned int orientation)
198 {
199 	if (orientation == 0)
200 		return TYPEC_ORIENTATION_NORMAL;
201 	else if (orientation == 1)
202 		return TYPEC_ORIENTATION_REVERSE;
203 	else
204 		return TYPEC_ORIENTATION_NONE;
205 }
206 
207 #define SC8180X_PORT_MASK		0x000000ff
208 #define SC8180X_ORIENTATION_MASK	0x0000ff00
209 #define SC8180X_MUX_MASK		0x00ff0000
210 #define SC8180X_MODE_MASK		0x3f000000
211 #define SC8180X_HPD_STATE_MASK		0x40000000
212 #define SC8180X_HPD_IRQ_MASK		0x80000000
213 
214 static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmode,
215 					       const void *data, size_t len)
216 {
217 	struct pmic_glink_altmode_port *alt_port;
218 	const struct usbc_sc8180x_notify *msg;
219 	u32 notification;
220 	u8 orientation;
221 	u8 hpd_state;
222 	u8 hpd_irq;
223 	u16 svid;
224 	u8 port;
225 	u8 mode;
226 	u8 mux;
227 
228 	if (len != sizeof(*msg)) {
229 		dev_warn(altmode->dev, "invalid length of USBC_NOTIFY indication: %zd\n", len);
230 		return;
231 	}
232 
233 	msg = data;
234 	notification = le32_to_cpu(msg->notification);
235 	port = FIELD_GET(SC8180X_PORT_MASK, notification);
236 	orientation = FIELD_GET(SC8180X_ORIENTATION_MASK, notification);
237 	mux = FIELD_GET(SC8180X_MUX_MASK, notification);
238 	mode = FIELD_GET(SC8180X_MODE_MASK, notification);
239 	hpd_state = FIELD_GET(SC8180X_HPD_STATE_MASK, notification);
240 	hpd_irq = FIELD_GET(SC8180X_HPD_IRQ_MASK, notification);
241 
242 	svid = mux == 2 ? USB_TYPEC_DP_SID : 0;
243 
244 	if (!altmode->ports[port].altmode) {
245 		dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
246 		return;
247 	}
248 
249 	alt_port = &altmode->ports[port];
250 	alt_port->orientation = pmic_glink_altmode_orientation(orientation);
251 	alt_port->svid = svid;
252 	alt_port->mode = mode;
253 	alt_port->hpd_state = hpd_state;
254 	alt_port->hpd_irq = hpd_irq;
255 	schedule_work(&alt_port->work);
256 }
257 
258 #define SC8280XP_DPAM_MASK	0x3f
259 #define SC8280XP_HPD_STATE_MASK BIT(6)
260 #define SC8280XP_HPD_IRQ_MASK	BIT(7)
261 
262 static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmode,
263 					       u16 svid, const void *data, size_t len)
264 {
265 	struct pmic_glink_altmode_port *alt_port;
266 	const struct usbc_notify *notify;
267 	u8 orientation;
268 	u8 hpd_state;
269 	u8 hpd_irq;
270 	u8 mode;
271 	u8 port;
272 
273 	if (len != sizeof(*notify)) {
274 		dev_warn(altmode->dev, "invalid length USBC_NOTIFY_IND: %zd\n",
275 			 len);
276 		return;
277 	}
278 
279 	notify = data;
280 
281 	port = notify->payload[0];
282 	orientation = notify->payload[1];
283 	mode = FIELD_GET(SC8280XP_DPAM_MASK, notify->payload[8]) - DPAM_HPD_A;
284 	hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]);
285 	hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]);
286 
287 	if (!altmode->ports[port].altmode) {
288 		dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
289 		return;
290 	}
291 
292 	alt_port = &altmode->ports[port];
293 	alt_port->orientation = pmic_glink_altmode_orientation(orientation);
294 	alt_port->svid = svid;
295 	alt_port->mode = mode;
296 	alt_port->hpd_state = hpd_state;
297 	alt_port->hpd_irq = hpd_irq;
298 	schedule_work(&alt_port->work);
299 }
300 
301 static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
302 {
303 	struct pmic_glink_altmode *altmode = priv;
304 	const struct pmic_glink_hdr *hdr = data;
305 	u16 opcode;
306 	u16 svid;
307 
308 	opcode = le32_to_cpu(hdr->opcode) & 0xff;
309 	svid = le32_to_cpu(hdr->opcode) >> 16;
310 
311 	switch (opcode) {
312 	case USBC_CMD_WRITE_REQ:
313 		complete(&altmode->pan_ack);
314 		break;
315 	case USBC_NOTIFY_IND:
316 		pmic_glink_altmode_sc8280xp_notify(altmode, svid, data, len);
317 		break;
318 	case USBC_SC8180X_NOTIFY_IND:
319 		pmic_glink_altmode_sc8180xp_notify(altmode, data, len);
320 		break;
321 	}
322 }
323 
324 static int pmic_glink_altmode_attach(struct drm_bridge *bridge,
325 				     enum drm_bridge_attach_flags flags)
326 {
327 	return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL;
328 }
329 
330 static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = {
331 	.attach = pmic_glink_altmode_attach,
332 };
333 
334 static void pmic_glink_altmode_put_mux(void *data)
335 {
336 	typec_mux_put(data);
337 }
338 
339 static void pmic_glink_altmode_put_switch(void *data)
340 {
341 	typec_switch_put(data);
342 }
343 
344 static void pmic_glink_altmode_enable_worker(struct work_struct *work)
345 {
346 	struct pmic_glink_altmode *altmode = work_to_altmode(work);
347 	int ret;
348 
349 	ret = pmic_glink_altmode_request(altmode, ALTMODE_PAN_EN, 0);
350 	if (ret)
351 		dev_err(altmode->dev, "failed to request altmode notifications\n");
352 }
353 
354 static void pmic_glink_altmode_pdr_notify(void *priv, int state)
355 {
356 	struct pmic_glink_altmode *altmode = priv;
357 
358 	if (state == SERVREG_SERVICE_STATE_UP)
359 		schedule_work(&altmode->enable_work);
360 }
361 
362 static const struct of_device_id pmic_glink_altmode_of_quirks[] = {
363 	{ .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)PMIC_GLINK_OWNER_USBC },
364 	{}
365 };
366 
367 static int pmic_glink_altmode_probe(struct auxiliary_device *adev,
368 				    const struct auxiliary_device_id *id)
369 {
370 	struct pmic_glink_altmode_port *alt_port;
371 	struct pmic_glink_altmode *altmode;
372 	const struct of_device_id *match;
373 	struct fwnode_handle *fwnode;
374 	struct device *dev = &adev->dev;
375 	u32 port;
376 	int ret;
377 
378 	altmode = devm_kzalloc(dev, sizeof(*altmode), GFP_KERNEL);
379 	if (!altmode)
380 		return -ENOMEM;
381 
382 	altmode->dev = dev;
383 
384 	match = of_match_device(pmic_glink_altmode_of_quirks, dev->parent);
385 	if (match)
386 		altmode->owner_id = (unsigned long)match->data;
387 	else
388 		altmode->owner_id = PMIC_GLINK_OWNER_USBC_PAN;
389 
390 	INIT_WORK(&altmode->enable_work, pmic_glink_altmode_enable_worker);
391 	init_completion(&altmode->pan_ack);
392 	mutex_init(&altmode->lock);
393 
394 	device_for_each_child_node(dev, fwnode) {
395 		ret = fwnode_property_read_u32(fwnode, "reg", &port);
396 		if (ret < 0) {
397 			dev_err(dev, "missing reg property of %pOFn\n", fwnode);
398 			return ret;
399 		}
400 
401 		if (port >= ARRAY_SIZE(altmode->ports)) {
402 			dev_warn(dev, "invalid connector number, ignoring\n");
403 			continue;
404 		}
405 
406 		if (altmode->ports[port].altmode) {
407 			dev_err(dev, "multiple connector definition for port %u\n", port);
408 			return -EINVAL;
409 		}
410 
411 		alt_port = &altmode->ports[port];
412 		alt_port->altmode = altmode;
413 		alt_port->index = port;
414 		INIT_WORK(&alt_port->work, pmic_glink_altmode_worker);
415 
416 		alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs;
417 		alt_port->bridge.of_node = to_of_node(fwnode);
418 		alt_port->bridge.ops = DRM_BRIDGE_OP_HPD;
419 		alt_port->bridge.type = DRM_MODE_CONNECTOR_USB;
420 
421 		ret = devm_drm_bridge_add(dev, &alt_port->bridge);
422 		if (ret)
423 			return ret;
424 
425 		alt_port->dp_alt.svid = USB_TYPEC_DP_SID;
426 		alt_port->dp_alt.mode = USB_TYPEC_DP_MODE;
427 		alt_port->dp_alt.active = 1;
428 
429 		alt_port->typec_mux = fwnode_typec_mux_get(fwnode);
430 		if (IS_ERR(alt_port->typec_mux))
431 			return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux),
432 					     "failed to acquire mode-switch for port: %d\n",
433 					     port);
434 
435 		ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux,
436 					       alt_port->typec_mux);
437 		if (ret)
438 			return ret;
439 
440 		alt_port->typec_switch = fwnode_typec_switch_get(fwnode);
441 		if (IS_ERR(alt_port->typec_switch))
442 			return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch),
443 					     "failed to acquire orientation-switch for port: %d\n",
444 					     port);
445 
446 		ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch,
447 					       alt_port->typec_switch);
448 		if (ret)
449 			return ret;
450 	}
451 
452 	altmode->client = devm_pmic_glink_register_client(dev,
453 							  altmode->owner_id,
454 							  pmic_glink_altmode_callback,
455 							  pmic_glink_altmode_pdr_notify,
456 							  altmode);
457 	return PTR_ERR_OR_ZERO(altmode->client);
458 }
459 
460 static const struct auxiliary_device_id pmic_glink_altmode_id_table[] = {
461 	{ .name = "pmic_glink.altmode", },
462 	{},
463 };
464 MODULE_DEVICE_TABLE(auxiliary, pmic_glink_altmode_id_table);
465 
466 static struct auxiliary_driver pmic_glink_altmode_driver = {
467 	.name = "pmic_glink_altmode",
468 	.probe = pmic_glink_altmode_probe,
469 	.id_table = pmic_glink_altmode_id_table,
470 };
471 
472 module_auxiliary_driver(pmic_glink_altmode_driver);
473 
474 MODULE_DESCRIPTION("Qualcomm PMIC GLINK Altmode driver");
475 MODULE_LICENSE("GPL");
476