Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm: bridge: anx7625: implement message sending

Swapping the data role requires sending the message to the other USB-C
side. Implement sending these messages through the OCM. The code is
largely based on the anx7411.c USB-C driver.

Reviewed-by: Xin Ji <xji@analogixsemi.com>
Link: https://patch.msgid.link/20260121-anx7625-typec-v2-3-d14f31256a17@oss.qualcomm.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

+80
+68
drivers/gpu/drm/bridge/analogix/anx7625.c
··· 1484 1484 } 1485 1485 1486 1486 #if IS_REACHABLE(CONFIG_TYPEC) 1487 + static u8 anx7625_checksum(u8 *buf, u8 len) 1488 + { 1489 + u8 ret = 0; 1490 + u8 i; 1491 + 1492 + for (i = 0; i < len; i++) 1493 + ret += buf[i]; 1494 + 1495 + return ret; 1496 + } 1497 + 1498 + static int anx7625_read_msg_ctrl_status(struct anx7625_data *ctx) 1499 + { 1500 + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF); 1501 + } 1502 + 1503 + static int anx7625_wait_msg_empty(struct anx7625_data *ctx) 1504 + { 1505 + int val; 1506 + 1507 + return readx_poll_timeout(anx7625_read_msg_ctrl_status, ctx, 1508 + val, (val < 0) || (val == 0), 1509 + 2000, 2000 * 150); 1510 + } 1511 + 1512 + static int anx7625_send_msg(struct anx7625_data *ctx, u8 type, u8 *buf, u8 size) 1513 + { 1514 + struct fw_msg *msg = &ctx->send_msg; 1515 + u8 crc; 1516 + int ret; 1517 + 1518 + size = min_t(u8, size, (u8)MAX_BUF_LEN); 1519 + memcpy(msg->buf, buf, size); 1520 + msg->msg_type = type; 1521 + 1522 + /* msg len equals buffer length + msg_type */ 1523 + msg->msg_len = size + 1; 1524 + 1525 + crc = anx7625_checksum((u8 *)msg, size + HEADER_LEN); 1526 + msg->buf[size] = 0 - crc; 1527 + 1528 + ret = anx7625_wait_msg_empty(ctx); 1529 + if (ret) 1530 + return ret; 1531 + 1532 + ret = anx7625_reg_block_write(ctx, ctx->i2c.rx_p0_client, 1533 + CMD_SEND_BUF + 1, size + HEADER_LEN, 1534 + &msg->msg_type); 1535 + ret |= anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, CMD_SEND_BUF, 1536 + msg->msg_len); 1537 + return ret; 1538 + } 1539 + 1540 + static int anx7625_typec_dr_set(struct typec_port *port, enum typec_data_role role) 1541 + { 1542 + struct anx7625_data *ctx = typec_get_drvdata(port); 1543 + 1544 + if (role == ctx->typec_data_role) 1545 + return 0; 1546 + 1547 + return anx7625_send_msg(ctx, 0x11, NULL, 0); 1548 + } 1549 + 1550 + static const struct typec_operations anx7625_typec_ops = { 1551 + .dr_set = anx7625_typec_dr_set, 1552 + }; 1553 + 1487 1554 static void anx7625_typec_set_orientation(struct anx7625_data *ctx) 1488 1555 { 1489 1556 u32 val = anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); ··· 1609 1542 typec_cap.orientation_aware = true; 1610 1543 1611 1544 typec_cap.driver_data = ctx; 1545 + typec_cap.ops = &anx7625_typec_ops; 1612 1546 1613 1547 ctx->typec_port = typec_register_port(ctx->dev, &typec_cap); 1614 1548 if (IS_ERR(ctx->typec_port))
+12
drivers/gpu/drm/bridge/analogix/anx7625.h
··· 67 67 #define CC2_RA BIT(5) 68 68 #define CC2_RP (BIT(6) | BIT(7)) 69 69 70 + #define CMD_SEND_BUF 0xC0 71 + #define CMD_RECV_BUF 0xE0 72 + 70 73 /******** END of I2C Address 0x58 ********/ 71 74 72 75 /***************************************************************/ ··· 465 462 struct typec_port; 466 463 struct usb_role_switch; 467 464 465 + #define MAX_BUF_LEN 30 466 + struct fw_msg { 467 + u8 msg_len; 468 + u8 msg_type; 469 + u8 buf[MAX_BUF_LEN]; 470 + } __packed; 471 + #define HEADER_LEN 2 472 + 468 473 struct anx7625_data { 469 474 struct anx7625_platform_data pdata; 470 475 struct platform_device *audio_pdev; ··· 508 497 struct drm_connector *connector; 509 498 struct mipi_dsi_device *dsi; 510 499 struct drm_dp_aux aux; 500 + struct fw_msg send_msg; 511 501 }; 512 502 513 503 #endif /* __ANX7625_H__ */