Lines Matching refs:ctx

106 typedef void (*sii8620_mt_msg_cb)(struct sii8620 *ctx,
109 typedef void (*sii8620_cb)(struct sii8620 *ctx, int ret);
131 static void sii8620_fetch_edid(struct sii8620 *ctx);
132 static void sii8620_set_upstream_edid(struct sii8620 *ctx);
133 static void sii8620_enable_hpd(struct sii8620 *ctx);
134 static void sii8620_mhl_disconnected(struct sii8620 *ctx);
135 static void sii8620_disconnect(struct sii8620 *ctx);
137 static int sii8620_clear_error(struct sii8620 *ctx) in sii8620_clear_error() argument
139 int ret = ctx->error; in sii8620_clear_error()
141 ctx->error = 0; in sii8620_clear_error()
145 static void sii8620_read_buf(struct sii8620 *ctx, u16 addr, u8 *buf, int len) in sii8620_read_buf() argument
147 struct device *dev = ctx->dev; in sii8620_read_buf()
166 if (ctx->error) in sii8620_read_buf()
175 ctx->error = ret < 0 ? ret : -EIO; in sii8620_read_buf()
179 static u8 sii8620_readb(struct sii8620 *ctx, u16 addr) in sii8620_readb() argument
183 sii8620_read_buf(ctx, addr, &ret, 1); in sii8620_readb()
187 static void sii8620_write_buf(struct sii8620 *ctx, u16 addr, const u8 *buf, in sii8620_write_buf() argument
190 struct device *dev = ctx->dev; in sii8620_write_buf()
200 if (ctx->error) in sii8620_write_buf()
206 ctx->error = -ENOMEM; in sii8620_write_buf()
223 ctx->error = ret ?: -EIO; in sii8620_write_buf()
230 #define sii8620_write(ctx, addr, arr...) \ argument
233 sii8620_write_buf(ctx, addr, d, ARRAY_SIZE(d)); \
236 static void __sii8620_write_seq(struct sii8620 *ctx, const u16 *seq, int len) in __sii8620_write_seq() argument
241 sii8620_write(ctx, seq[i], seq[i + 1]); in __sii8620_write_seq()
244 #define sii8620_write_seq(ctx, seq...) \ argument
247 __sii8620_write_seq(ctx, d, ARRAY_SIZE(d)); \
250 #define sii8620_write_seq_static(ctx, seq...) \ argument
253 __sii8620_write_seq(ctx, d, ARRAY_SIZE(d)); \
256 static void sii8620_setbits(struct sii8620 *ctx, u16 addr, u8 mask, u8 val) in sii8620_setbits() argument
258 val = (val & mask) | (sii8620_readb(ctx, addr) & ~mask); in sii8620_setbits()
259 sii8620_write(ctx, addr, val); in sii8620_setbits()
262 static inline bool sii8620_is_mhl3(struct sii8620 *ctx) in sii8620_is_mhl3() argument
264 return ctx->mode >= CM_MHL3; in sii8620_is_mhl3()
267 static void sii8620_mt_cleanup(struct sii8620 *ctx) in sii8620_mt_cleanup() argument
271 list_for_each_entry_safe(msg, n, &ctx->mt_queue, node) { in sii8620_mt_cleanup()
275 ctx->mt_state = MT_STATE_READY; in sii8620_mt_cleanup()
278 static void sii8620_mt_work(struct sii8620 *ctx) in sii8620_mt_work() argument
282 if (ctx->error) in sii8620_mt_work()
284 if (ctx->mt_state == MT_STATE_BUSY || list_empty(&ctx->mt_queue)) in sii8620_mt_work()
287 if (ctx->mt_state == MT_STATE_DONE) { in sii8620_mt_work()
288 ctx->mt_state = MT_STATE_READY; in sii8620_mt_work()
289 msg = list_first_entry(&ctx->mt_queue, struct sii8620_mt_msg, in sii8620_mt_work()
293 msg->recv(ctx, msg); in sii8620_mt_work()
295 msg->continuation(ctx, msg->ret); in sii8620_mt_work()
299 if (ctx->mt_state != MT_STATE_READY || list_empty(&ctx->mt_queue)) in sii8620_mt_work()
302 ctx->mt_state = MT_STATE_BUSY; in sii8620_mt_work()
303 msg = list_first_entry(&ctx->mt_queue, struct sii8620_mt_msg, node); in sii8620_mt_work()
305 msg->send(ctx, msg); in sii8620_mt_work()
308 static void sii8620_enable_gen2_write_burst(struct sii8620 *ctx) in sii8620_enable_gen2_write_burst() argument
312 if (ctx->gen2_write_burst) in sii8620_enable_gen2_write_burst()
315 if (ctx->mode >= CM_MHL1) in sii8620_enable_gen2_write_burst()
318 sii8620_write_seq(ctx, in sii8620_enable_gen2_write_burst()
322 ctx->gen2_write_burst = 1; in sii8620_enable_gen2_write_burst()
325 static void sii8620_disable_gen2_write_burst(struct sii8620 *ctx) in sii8620_disable_gen2_write_burst() argument
327 if (!ctx->gen2_write_burst) in sii8620_disable_gen2_write_burst()
330 sii8620_write_seq_static(ctx, in sii8620_disable_gen2_write_burst()
334 ctx->gen2_write_burst = 0; in sii8620_disable_gen2_write_burst()
337 static void sii8620_start_gen2_write_burst(struct sii8620 *ctx) in sii8620_start_gen2_write_burst() argument
339 sii8620_write_seq_static(ctx, in sii8620_start_gen2_write_burst()
348 sii8620_enable_gen2_write_burst(ctx); in sii8620_start_gen2_write_burst()
351 static void sii8620_mt_msc_cmd_send(struct sii8620 *ctx, in sii8620_mt_msc_cmd_send() argument
357 sii8620_enable_gen2_write_burst(ctx); in sii8620_mt_msc_cmd_send()
359 sii8620_disable_gen2_write_burst(ctx); in sii8620_mt_msc_cmd_send()
364 sii8620_write_buf(ctx, REG_MSC_CMD_OR_OFFSET, msg->reg + 1, 2); in sii8620_mt_msc_cmd_send()
365 sii8620_write(ctx, REG_MSC_COMMAND_START, in sii8620_mt_msc_cmd_send()
369 sii8620_write_buf(ctx, REG_MSC_CMD_OR_OFFSET, msg->reg, 3); in sii8620_mt_msc_cmd_send()
370 sii8620_write(ctx, REG_MSC_COMMAND_START, in sii8620_mt_msc_cmd_send()
375 sii8620_write(ctx, REG_MSC_CMD_OR_OFFSET, msg->reg[1]); in sii8620_mt_msc_cmd_send()
376 sii8620_write(ctx, REG_MSC_COMMAND_START, in sii8620_mt_msc_cmd_send()
380 dev_err(ctx->dev, "%s: command %#x not supported\n", __func__, in sii8620_mt_msc_cmd_send()
385 static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx) in sii8620_mt_msg_new() argument
390 ctx->error = -ENOMEM; in sii8620_mt_msg_new()
392 list_add_tail(&msg->node, &ctx->mt_queue); in sii8620_mt_msg_new()
397 static void sii8620_mt_set_cont(struct sii8620 *ctx, sii8620_cb cont) in sii8620_mt_set_cont() argument
401 if (ctx->error) in sii8620_mt_set_cont()
404 if (list_empty(&ctx->mt_queue)) { in sii8620_mt_set_cont()
405 ctx->error = -EINVAL; in sii8620_mt_set_cont()
408 msg = list_last_entry(&ctx->mt_queue, struct sii8620_mt_msg, node); in sii8620_mt_set_cont()
412 static void sii8620_mt_msc_cmd(struct sii8620 *ctx, u8 cmd, u8 arg1, u8 arg2) in sii8620_mt_msc_cmd() argument
414 struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx); in sii8620_mt_msc_cmd()
425 static void sii8620_mt_write_stat(struct sii8620 *ctx, u8 reg, u8 val) in sii8620_mt_write_stat() argument
427 sii8620_mt_msc_cmd(ctx, MHL_WRITE_STAT, reg, val); in sii8620_mt_write_stat()
430 static inline void sii8620_mt_set_int(struct sii8620 *ctx, u8 irq, u8 mask) in sii8620_mt_set_int() argument
432 sii8620_mt_msc_cmd(ctx, MHL_SET_INT, irq, mask); in sii8620_mt_set_int()
435 static void sii8620_mt_msc_msg(struct sii8620 *ctx, u8 cmd, u8 data) in sii8620_mt_msc_msg() argument
437 sii8620_mt_msc_cmd(ctx, MHL_MSC_MSG, cmd, data); in sii8620_mt_msc_msg()
440 static void sii8620_mt_rap(struct sii8620 *ctx, u8 code) in sii8620_mt_rap() argument
442 sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RAP, code); in sii8620_mt_rap()
445 static void sii8620_mt_rcpk(struct sii8620 *ctx, u8 code) in sii8620_mt_rcpk() argument
447 sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPK, code); in sii8620_mt_rcpk()
450 static void sii8620_mt_rcpe(struct sii8620 *ctx, u8 code) in sii8620_mt_rcpe() argument
452 sii8620_mt_msc_msg(ctx, MHL_MSC_MSG_RCPE, code); in sii8620_mt_rcpe()
455 static void sii8620_mt_read_devcap_send(struct sii8620 *ctx, in sii8620_mt_read_devcap_send() argument
465 sii8620_write_seq(ctx, in sii8620_mt_read_devcap_send()
481 static void sii8620_identify_sink(struct sii8620 *ctx) in sii8620_identify_sink() argument
490 struct device *dev = ctx->dev; in sii8620_identify_sink()
492 if (!ctx->sink_detected || !ctx->devcap_read) in sii8620_identify_sink()
495 sii8620_fetch_edid(ctx); in sii8620_identify_sink()
496 if (!ctx->edid) { in sii8620_identify_sink()
497 dev_err(ctx->dev, "Cannot fetch EDID\n"); in sii8620_identify_sink()
498 sii8620_mhl_disconnected(ctx); in sii8620_identify_sink()
501 sii8620_set_upstream_edid(ctx); in sii8620_identify_sink()
503 if (drm_detect_hdmi_monitor(ctx->edid)) in sii8620_identify_sink()
504 ctx->sink_type = SINK_HDMI; in sii8620_identify_sink()
506 ctx->sink_type = SINK_DVI; in sii8620_identify_sink()
508 drm_edid_get_monitor_name(ctx->edid, sink_name, ARRAY_SIZE(sink_name)); in sii8620_identify_sink()
511 sink_str[ctx->sink_type], sink_name); in sii8620_identify_sink()
514 static void sii8620_mr_devcap(struct sii8620 *ctx) in sii8620_mr_devcap() argument
517 struct device *dev = ctx->dev; in sii8620_mr_devcap()
519 sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, dcap, MHL_DCAP_SIZE); in sii8620_mr_devcap()
520 if (ctx->error < 0) in sii8620_mr_devcap()
528 sii8620_update_array(ctx->devcap, dcap, MHL_DCAP_SIZE); in sii8620_mr_devcap()
529 ctx->devcap_read = true; in sii8620_mr_devcap()
530 sii8620_identify_sink(ctx); in sii8620_mr_devcap()
533 static void sii8620_mr_xdevcap(struct sii8620 *ctx) in sii8620_mr_xdevcap() argument
535 sii8620_read_buf(ctx, REG_EDID_FIFO_RD_DATA, ctx->xdevcap, in sii8620_mr_xdevcap()
539 static void sii8620_mt_read_devcap_recv(struct sii8620 *ctx, in sii8620_mt_read_devcap_recv() argument
549 sii8620_write_seq(ctx, in sii8620_mt_read_devcap_recv()
557 sii8620_mr_xdevcap(ctx); in sii8620_mt_read_devcap_recv()
559 sii8620_mr_devcap(ctx); in sii8620_mt_read_devcap_recv()
562 static void sii8620_mt_read_devcap(struct sii8620 *ctx, bool xdevcap) in sii8620_mt_read_devcap() argument
564 struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx); in sii8620_mt_read_devcap()
574 static void sii8620_mt_read_devcap_reg_recv(struct sii8620 *ctx, in sii8620_mt_read_devcap_reg_recv() argument
580 ctx->xdevcap[reg] = msg->ret; in sii8620_mt_read_devcap_reg_recv()
582 ctx->devcap[reg] = msg->ret; in sii8620_mt_read_devcap_reg_recv()
585 static void sii8620_mt_read_devcap_reg(struct sii8620 *ctx, u8 reg) in sii8620_mt_read_devcap_reg() argument
587 struct sii8620_mt_msg *msg = sii8620_mt_msg_new(ctx); in sii8620_mt_read_devcap_reg()
598 static inline void sii8620_mt_read_xdevcap_reg(struct sii8620 *ctx, u8 reg) in sii8620_mt_read_xdevcap_reg() argument
600 sii8620_mt_read_devcap_reg(ctx, reg | 0x80); in sii8620_mt_read_xdevcap_reg()
603 static void *sii8620_burst_get_tx_buf(struct sii8620 *ctx, int len) in sii8620_burst_get_tx_buf() argument
605 u8 *buf = &ctx->burst.tx_buf[ctx->burst.tx_count]; in sii8620_burst_get_tx_buf()
608 if (ctx->burst.tx_count + size >= ARRAY_SIZE(ctx->burst.tx_buf)) { in sii8620_burst_get_tx_buf()
609 dev_err(ctx->dev, "TX-BLK buffer exhausted\n"); in sii8620_burst_get_tx_buf()
610 ctx->error = -EINVAL; in sii8620_burst_get_tx_buf()
614 ctx->burst.tx_count += size; in sii8620_burst_get_tx_buf()
620 static u8 *sii8620_burst_get_rx_buf(struct sii8620 *ctx, int len) in sii8620_burst_get_rx_buf() argument
622 u8 *buf = &ctx->burst.rx_buf[ctx->burst.rx_count]; in sii8620_burst_get_rx_buf()
625 if (ctx->burst.rx_count + size >= ARRAY_SIZE(ctx->burst.rx_buf)) { in sii8620_burst_get_rx_buf()
626 dev_err(ctx->dev, "RX-BLK buffer exhausted\n"); in sii8620_burst_get_rx_buf()
627 ctx->error = -EINVAL; in sii8620_burst_get_rx_buf()
631 ctx->burst.rx_count += size; in sii8620_burst_get_rx_buf()
637 static void sii8620_burst_send(struct sii8620 *ctx) in sii8620_burst_send() argument
639 int tx_left = ctx->burst.tx_count; in sii8620_burst_send()
640 u8 *d = ctx->burst.tx_buf; in sii8620_burst_send()
645 if (ctx->burst.r_count + len > ctx->burst.r_size) in sii8620_burst_send()
647 d[0] = min(ctx->burst.rx_ack, 255); in sii8620_burst_send()
648 ctx->burst.rx_ack -= d[0]; in sii8620_burst_send()
649 sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, d, len); in sii8620_burst_send()
650 ctx->burst.r_count += len; in sii8620_burst_send()
655 ctx->burst.tx_count = tx_left; in sii8620_burst_send()
657 while (ctx->burst.rx_ack > 0) { in sii8620_burst_send()
658 u8 b[2] = { min(ctx->burst.rx_ack, 255), 0 }; in sii8620_burst_send()
660 if (ctx->burst.r_count + 2 > ctx->burst.r_size) in sii8620_burst_send()
662 ctx->burst.rx_ack -= b[0]; in sii8620_burst_send()
663 sii8620_write_buf(ctx, REG_EMSC_XMIT_WRITE_PORT, b, 2); in sii8620_burst_send()
664 ctx->burst.r_count += 2; in sii8620_burst_send()
668 static void sii8620_burst_receive(struct sii8620 *ctx) in sii8620_burst_receive() argument
673 sii8620_read_buf(ctx, REG_EMSCRFIFOBCNTL, buf, 2); in sii8620_burst_receive()
678 sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, buf, len); in sii8620_burst_receive()
680 ctx->burst.rx_ack += len - 1; in sii8620_burst_receive()
681 ctx->burst.r_count -= buf[1]; in sii8620_burst_receive()
682 if (ctx->burst.r_count < 0) in sii8620_burst_receive()
683 ctx->burst.r_count = 0; in sii8620_burst_receive()
689 d = sii8620_burst_get_rx_buf(ctx, len); in sii8620_burst_receive()
692 sii8620_read_buf(ctx, REG_EMSC_RCV_READ_PORT, d, len); in sii8620_burst_receive()
694 ctx->burst.rx_ack += len; in sii8620_burst_receive()
698 static void sii8620_burst_tx_rbuf_info(struct sii8620 *ctx, int size) in sii8620_burst_tx_rbuf_info() argument
701 sii8620_burst_get_tx_buf(ctx, sizeof(*d)); in sii8620_burst_tx_rbuf_info()
727 static void sii8620_burst_tx_bits_per_pixel_fmt(struct sii8620 *ctx, u8 fmt) in sii8620_burst_tx_bits_per_pixel_fmt() argument
732 d = sii8620_burst_get_tx_buf(ctx, size); in sii8620_burst_tx_bits_per_pixel_fmt()
743 static void sii8620_burst_rx_all(struct sii8620 *ctx) in sii8620_burst_rx_all() argument
745 u8 *d = ctx->burst.rx_buf; in sii8620_burst_rx_all()
746 int count = ctx->burst.rx_count; in sii8620_burst_rx_all()
754 ctx->burst.r_size = get_unaligned_le16(&d[2]); in sii8620_burst_rx_all()
762 ctx->burst.rx_count = 0; in sii8620_burst_rx_all()
765 static void sii8620_fetch_edid(struct sii8620 *ctx) in sii8620_fetch_edid() argument
773 sii8620_readb(ctx, REG_CBUS_STATUS); in sii8620_fetch_edid()
774 lm_ddc = sii8620_readb(ctx, REG_LM_DDC); in sii8620_fetch_edid()
775 ddc_cmd = sii8620_readb(ctx, REG_DDC_CMD); in sii8620_fetch_edid()
777 sii8620_write_seq(ctx, in sii8620_fetch_edid()
786 u8 ddc_stat = sii8620_readb(ctx, REG_DDC_STATUS); in sii8620_fetch_edid()
790 sii8620_write(ctx, REG_DDC_STATUS, in sii8620_fetch_edid()
794 sii8620_write(ctx, REG_DDC_ADDR, 0x50 << 1); in sii8620_fetch_edid()
798 ctx->error = -ENOMEM; in sii8620_fetch_edid()
804 sii8620_readb(ctx, REG_DDC_STATUS); in sii8620_fetch_edid()
805 sii8620_write_seq(ctx, in sii8620_fetch_edid()
810 sii8620_write_seq(ctx, in sii8620_fetch_edid()
821 cbus = sii8620_readb(ctx, REG_CBUS_STATUS); in sii8620_fetch_edid()
828 if (sii8620_readb(ctx, REG_DDC_DOUT_CNT) in sii8620_fetch_edid()
832 int3 = sii8620_readb(ctx, REG_INTR3); in sii8620_fetch_edid()
835 ctx->error = -ETIMEDOUT; in sii8620_fetch_edid()
836 dev_err(ctx->dev, "timeout during EDID read\n"); in sii8620_fetch_edid()
844 sii8620_read_buf(ctx, REG_DDC_DATA, edid + fetched, FETCH_SIZE); in sii8620_fetch_edid()
855 ctx->error = -ENOMEM; in sii8620_fetch_edid()
863 sii8620_write_seq(ctx, in sii8620_fetch_edid()
869 kfree(ctx->edid); in sii8620_fetch_edid()
870 ctx->edid = (struct edid *)edid; in sii8620_fetch_edid()
873 static void sii8620_set_upstream_edid(struct sii8620 *ctx) in sii8620_set_upstream_edid() argument
875 sii8620_setbits(ctx, REG_DPD, BIT_DPD_PDNRX12 | BIT_DPD_PDIDCK_N in sii8620_set_upstream_edid()
878 sii8620_write_seq_static(ctx, in sii8620_set_upstream_edid()
885 sii8620_setbits(ctx, REG_RX_HDMI_CLR_BUFFER, in sii8620_set_upstream_edid()
888 sii8620_write_seq_static(ctx, in sii8620_set_upstream_edid()
894 sii8620_write_buf(ctx, REG_EDID_FIFO_WR_DATA, (u8 *)ctx->edid, in sii8620_set_upstream_edid()
895 (ctx->edid->extensions + 1) * EDID_LENGTH); in sii8620_set_upstream_edid()
897 sii8620_write_seq_static(ctx, in sii8620_set_upstream_edid()
906 static void sii8620_xtal_set_rate(struct sii8620 *ctx) in sii8620_xtal_set_rate() argument
919 unsigned long rate = clk_get_rate(ctx->clk_xtal) / 1000; in sii8620_xtal_set_rate()
927 dev_err(ctx->dev, "xtal clock rate(%lukHz) not supported, setting MHL for %ukHz.\n", in sii8620_xtal_set_rate()
930 sii8620_write(ctx, REG_DIV_CTL_MAIN, rates[i].div); in sii8620_xtal_set_rate()
931 sii8620_write(ctx, REG_HDCP2X_TP1, rates[i].tp1); in sii8620_xtal_set_rate()
934 static int sii8620_hw_on(struct sii8620 *ctx) in sii8620_hw_on() argument
938 ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies); in sii8620_hw_on()
943 ret = clk_prepare_enable(ctx->clk_xtal); in sii8620_hw_on()
948 gpiod_set_value(ctx->gpio_reset, 0); in sii8620_hw_on()
954 static int sii8620_hw_off(struct sii8620 *ctx) in sii8620_hw_off() argument
956 clk_disable_unprepare(ctx->clk_xtal); in sii8620_hw_off()
957 gpiod_set_value(ctx->gpio_reset, 1); in sii8620_hw_off()
958 return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies); in sii8620_hw_off()
961 static void sii8620_cbus_reset(struct sii8620 *ctx) in sii8620_cbus_reset() argument
963 sii8620_write(ctx, REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST in sii8620_cbus_reset()
966 sii8620_write(ctx, REG_PWD_SRST, BIT_PWD_SRST_CBUS_RST_SW_EN); in sii8620_cbus_reset()
969 static void sii8620_set_auto_zone(struct sii8620 *ctx) in sii8620_set_auto_zone() argument
971 if (ctx->mode != CM_MHL1) { in sii8620_set_auto_zone()
972 sii8620_write_seq_static(ctx, in sii8620_set_auto_zone()
979 sii8620_write_seq_static(ctx, in sii8620_set_auto_zone()
987 static void sii8620_stop_video(struct sii8620 *ctx) in sii8620_stop_video() argument
991 sii8620_write_seq_static(ctx, in sii8620_stop_video()
998 switch (ctx->sink_type) { in sii8620_stop_video()
1011 sii8620_write(ctx, REG_TPI_SC, val); in sii8620_stop_video()
1014 static void sii8620_set_format(struct sii8620 *ctx) in sii8620_set_format() argument
1018 if (sii8620_is_mhl3(ctx)) { in sii8620_set_format()
1019 sii8620_setbits(ctx, REG_M3_P0CTRL, in sii8620_set_format()
1021 ctx->use_packed_pixel ? ~0 : 0); in sii8620_set_format()
1023 if (ctx->use_packed_pixel) { in sii8620_set_format()
1024 sii8620_write_seq_static(ctx, in sii8620_set_format()
1030 sii8620_write_seq_static(ctx, in sii8620_set_format()
1038 if (ctx->use_packed_pixel) in sii8620_set_format()
1043 sii8620_write_seq(ctx, in sii8620_set_format()
1096 static void sii8620_set_infoframes(struct sii8620 *ctx, in sii8620_set_infoframes() argument
1106 if (ctx->use_packed_pixel) in sii8620_set_infoframes()
1112 sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3); in sii8620_set_infoframes()
1114 if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) { in sii8620_set_infoframes()
1115 sii8620_write(ctx, REG_TPI_SC, in sii8620_set_infoframes()
1117 sii8620_write(ctx, REG_PKT_FILTER_0, in sii8620_set_infoframes()
1125 sii8620_write(ctx, REG_PKT_FILTER_0, in sii8620_set_infoframes()
1134 sii8620_write(ctx, REG_TPI_INFO_FSEL, BIT_TPI_INFO_FSEL_EN in sii8620_set_infoframes()
1139 sii8620_write_buf(ctx, REG_TPI_INFO_B0, buf, ret); in sii8620_set_infoframes()
1142 static void sii8620_start_video(struct sii8620 *ctx) in sii8620_start_video() argument
1145 &ctx->bridge.encoder->crtc->state->adjusted_mode; in sii8620_start_video()
1147 if (!sii8620_is_mhl3(ctx)) in sii8620_start_video()
1148 sii8620_stop_video(ctx); in sii8620_start_video()
1150 if (ctx->sink_type == SINK_DVI && !sii8620_is_mhl3(ctx)) { in sii8620_start_video()
1151 sii8620_write(ctx, REG_RX_HDMI_CTRL2, in sii8620_start_video()
1153 sii8620_write(ctx, REG_TPI_SC, 0); in sii8620_start_video()
1157 sii8620_write_seq_static(ctx, in sii8620_start_video()
1162 sii8620_set_format(ctx); in sii8620_start_video()
1164 if (!sii8620_is_mhl3(ctx)) { in sii8620_start_video()
1167 if (ctx->use_packed_pixel) in sii8620_start_video()
1172 sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), link_mode); in sii8620_start_video()
1173 sii8620_set_auto_zone(ctx); in sii8620_start_video()
1189 int clk = mode->clock * (ctx->use_packed_pixel ? 2 : 3); in sii8620_start_video()
1199 sii8620_burst_tx_bits_per_pixel_fmt(ctx, ctx->use_packed_pixel); in sii8620_start_video()
1200 sii8620_burst_send(ctx); in sii8620_start_video()
1201 sii8620_write_seq(ctx, in sii8620_start_video()
1204 sii8620_setbits(ctx, REG_M3_P0CTRL, in sii8620_start_video()
1207 sii8620_setbits(ctx, REG_M3_POSTM, MSK_M3_POSTM_RRP_DECODE, in sii8620_start_video()
1209 sii8620_write_seq_static(ctx, in sii8620_start_video()
1214 sii8620_mt_write_stat(ctx, MHL_XDS_REG(AVLINK_MODE_CONTROL), in sii8620_start_video()
1218 sii8620_set_infoframes(ctx, mode); in sii8620_start_video()
1221 static void sii8620_disable_hpd(struct sii8620 *ctx) in sii8620_disable_hpd() argument
1223 sii8620_setbits(ctx, REG_EDID_CTRL, BIT_EDID_CTRL_EDID_PRIME_VALID, 0); in sii8620_disable_hpd()
1224 sii8620_write_seq_static(ctx, in sii8620_disable_hpd()
1230 static void sii8620_enable_hpd(struct sii8620 *ctx) in sii8620_enable_hpd() argument
1232 sii8620_setbits(ctx, REG_TMDS_CSTAT_P3, in sii8620_enable_hpd()
1235 sii8620_write_seq_static(ctx, in sii8620_enable_hpd()
1241 static void sii8620_mhl_discover(struct sii8620 *ctx) in sii8620_mhl_discover() argument
1243 sii8620_write_seq_static(ctx, in sii8620_mhl_discover()
1282 static void sii8620_peer_specific_init(struct sii8620 *ctx) in sii8620_peer_specific_init() argument
1284 if (sii8620_is_mhl3(ctx)) in sii8620_peer_specific_init()
1285 sii8620_write_seq_static(ctx, in sii8620_peer_specific_init()
1291 sii8620_write_seq_static(ctx, in sii8620_peer_specific_init()
1305 static void sii8620_set_dev_cap(struct sii8620 *ctx) in sii8620_set_dev_cap() argument
1334 sii8620_write_buf(ctx, REG_MHL_DEVCAP_0, devcap, ARRAY_SIZE(devcap)); in sii8620_set_dev_cap()
1335 sii8620_write_buf(ctx, REG_MHL_EXTDEVCAP_0, xdcap, ARRAY_SIZE(xdcap)); in sii8620_set_dev_cap()
1338 static void sii8620_mhl_init(struct sii8620 *ctx) in sii8620_mhl_init() argument
1340 sii8620_write_seq_static(ctx, in sii8620_mhl_init()
1346 sii8620_peer_specific_init(ctx); in sii8620_mhl_init()
1348 sii8620_disable_hpd(ctx); in sii8620_mhl_init()
1350 sii8620_write_seq_static(ctx, in sii8620_mhl_init()
1361 sii8620_setbits(ctx, REG_LM_DDC, BIT_LM_DDC_SW_TPI_EN_DISABLED, 0); in sii8620_mhl_init()
1362 sii8620_write_seq_static(ctx, in sii8620_mhl_init()
1367 sii8620_set_dev_cap(ctx); in sii8620_mhl_init()
1368 sii8620_write_seq_static(ctx, in sii8620_mhl_init()
1376 sii8620_start_gen2_write_burst(ctx); in sii8620_mhl_init()
1377 sii8620_write_seq_static(ctx, in sii8620_mhl_init()
1392 sii8620_disable_gen2_write_burst(ctx); in sii8620_mhl_init()
1394 sii8620_mt_write_stat(ctx, MHL_DST_REG(VERSION), SII8620_MHL_VERSION); in sii8620_mhl_init()
1395 sii8620_mt_write_stat(ctx, MHL_DST_REG(CONNECTED_RDY), in sii8620_mhl_init()
1398 sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE), MHL_INT_RC_DCAP_CHG); in sii8620_mhl_init()
1401 static void sii8620_emsc_enable(struct sii8620 *ctx) in sii8620_emsc_enable() argument
1405 sii8620_setbits(ctx, REG_GENCTL, BIT_GENCTL_EMSC_EN in sii8620_emsc_enable()
1408 sii8620_setbits(ctx, REG_GENCTL, BIT_GENCTL_CLR_EMSC_RFIFO in sii8620_emsc_enable()
1410 sii8620_setbits(ctx, REG_COMMECNT, BIT_COMMECNT_I2C_TO_EMSC_EN, ~0); in sii8620_emsc_enable()
1411 reg = sii8620_readb(ctx, REG_EMSCINTR); in sii8620_emsc_enable()
1412 sii8620_write(ctx, REG_EMSCINTR, reg); in sii8620_emsc_enable()
1413 sii8620_write(ctx, REG_EMSCINTRMASK, BIT_EMSCINTR_SPI_DVLD); in sii8620_emsc_enable()
1416 static int sii8620_wait_for_fsm_state(struct sii8620 *ctx, u8 state) in sii8620_wait_for_fsm_state() argument
1421 u8 s = sii8620_readb(ctx, REG_COC_STAT_0); in sii8620_wait_for_fsm_state()
1432 static void sii8620_set_mode(struct sii8620 *ctx, enum sii8620_mode mode) in sii8620_set_mode() argument
1436 if (ctx->mode == mode) in sii8620_set_mode()
1441 sii8620_write_seq_static(ctx, in sii8620_set_mode()
1448 ctx->mode = mode; in sii8620_set_mode()
1451 sii8620_write(ctx, REG_M3_CTRL, VAL_M3_CTRL_MHL3_VALUE); in sii8620_set_mode()
1452 ctx->mode = mode; in sii8620_set_mode()
1455 sii8620_emsc_enable(ctx); in sii8620_set_mode()
1456 sii8620_write_seq_static(ctx, in sii8620_set_mode()
1476 ret = sii8620_wait_for_fsm_state(ctx, 0x03); in sii8620_set_mode()
1477 sii8620_write_seq_static(ctx, in sii8620_set_mode()
1482 sii8620_write(ctx, REG_CBUS3_CNVT, 0x85); in sii8620_set_mode()
1484 sii8620_disconnect(ctx); in sii8620_set_mode()
1487 ctx->mode = mode; in sii8620_set_mode()
1490 dev_err(ctx->dev, "%s mode %d not supported\n", __func__, mode); in sii8620_set_mode()
1494 sii8620_set_auto_zone(ctx); in sii8620_set_mode()
1499 sii8620_write_seq_static(ctx, in sii8620_set_mode()
1510 static void sii8620_hpd_unplugged(struct sii8620 *ctx) in sii8620_hpd_unplugged() argument
1512 sii8620_disable_hpd(ctx); in sii8620_hpd_unplugged()
1513 ctx->sink_type = SINK_NONE; in sii8620_hpd_unplugged()
1514 ctx->sink_detected = false; in sii8620_hpd_unplugged()
1515 ctx->feature_complete = false; in sii8620_hpd_unplugged()
1516 kfree(ctx->edid); in sii8620_hpd_unplugged()
1517 ctx->edid = NULL; in sii8620_hpd_unplugged()
1520 static void sii8620_disconnect(struct sii8620 *ctx) in sii8620_disconnect() argument
1522 sii8620_disable_gen2_write_burst(ctx); in sii8620_disconnect()
1523 sii8620_stop_video(ctx); in sii8620_disconnect()
1525 sii8620_cbus_reset(ctx); in sii8620_disconnect()
1526 sii8620_set_mode(ctx, CM_DISCONNECTED); in sii8620_disconnect()
1527 sii8620_write_seq_static(ctx, in sii8620_disconnect()
1547 sii8620_hpd_unplugged(ctx); in sii8620_disconnect()
1548 sii8620_write_seq_static(ctx, in sii8620_disconnect()
1591 memset(ctx->stat, 0, sizeof(ctx->stat)); in sii8620_disconnect()
1592 memset(ctx->xstat, 0, sizeof(ctx->xstat)); in sii8620_disconnect()
1593 memset(ctx->devcap, 0, sizeof(ctx->devcap)); in sii8620_disconnect()
1594 memset(ctx->xdevcap, 0, sizeof(ctx->xdevcap)); in sii8620_disconnect()
1595 ctx->devcap_read = false; in sii8620_disconnect()
1596 ctx->cbus_status = 0; in sii8620_disconnect()
1597 sii8620_mt_cleanup(ctx); in sii8620_disconnect()
1600 static void sii8620_mhl_disconnected(struct sii8620 *ctx) in sii8620_mhl_disconnected() argument
1602 sii8620_write_seq_static(ctx, in sii8620_mhl_disconnected()
1607 sii8620_disconnect(ctx); in sii8620_mhl_disconnected()
1610 static void sii8620_irq_disc(struct sii8620 *ctx) in sii8620_irq_disc() argument
1612 u8 stat = sii8620_readb(ctx, REG_CBUS_DISC_INTR0); in sii8620_irq_disc()
1615 sii8620_mhl_disconnected(ctx); in sii8620_irq_disc()
1618 u8 stat2 = sii8620_readb(ctx, REG_DISC_STAT2); in sii8620_irq_disc()
1621 sii8620_mhl_discover(ctx); in sii8620_irq_disc()
1623 sii8620_write_seq_static(ctx, in sii8620_irq_disc()
1635 sii8620_mhl_init(ctx); in sii8620_irq_disc()
1637 sii8620_write(ctx, REG_CBUS_DISC_INTR0, stat); in sii8620_irq_disc()
1640 static void sii8620_read_burst(struct sii8620 *ctx) in sii8620_read_burst() argument
1644 sii8620_read_buf(ctx, REG_MDT_RCV_READ_PORT, buf, ARRAY_SIZE(buf)); in sii8620_read_burst()
1645 sii8620_write(ctx, REG_MDT_RCV_CTRL, BIT_MDT_RCV_CTRL_MDT_RCV_EN | in sii8620_read_burst()
1648 sii8620_readb(ctx, REG_MDT_RFIFO_STAT); in sii8620_read_burst()
1651 static void sii8620_irq_g2wb(struct sii8620 *ctx) in sii8620_irq_g2wb() argument
1653 u8 stat = sii8620_readb(ctx, REG_MDT_INT_0); in sii8620_irq_g2wb()
1656 if (sii8620_is_mhl3(ctx)) in sii8620_irq_g2wb()
1657 sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE), in sii8620_irq_g2wb()
1661 sii8620_read_burst(ctx); in sii8620_irq_g2wb()
1664 sii8620_write(ctx, REG_MDT_XMIT_CTRL, 0); in sii8620_irq_g2wb()
1666 sii8620_write(ctx, REG_MDT_INT_0, stat); in sii8620_irq_g2wb()
1669 static void sii8620_status_dcap_ready(struct sii8620 *ctx) in sii8620_status_dcap_ready() argument
1673 mode = ctx->stat[MHL_DST_VERSION] >= 0x30 ? CM_MHL3 : CM_MHL1; in sii8620_status_dcap_ready()
1674 if (mode > ctx->mode) in sii8620_status_dcap_ready()
1675 sii8620_set_mode(ctx, mode); in sii8620_status_dcap_ready()
1676 sii8620_peer_specific_init(ctx); in sii8620_status_dcap_ready()
1677 sii8620_write(ctx, REG_INTR9_MASK, BIT_INTR9_DEVCAP_DONE in sii8620_status_dcap_ready()
1681 static void sii8620_status_changed_path(struct sii8620 *ctx) in sii8620_status_changed_path() argument
1685 if (ctx->use_packed_pixel) in sii8620_status_changed_path()
1690 if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED) in sii8620_status_changed_path()
1693 sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), in sii8620_status_changed_path()
1697 static void sii8620_msc_mr_write_stat(struct sii8620 *ctx) in sii8620_msc_mr_write_stat() argument
1701 sii8620_read_buf(ctx, REG_MHL_STAT_0, st, MHL_DST_SIZE); in sii8620_msc_mr_write_stat()
1702 sii8620_read_buf(ctx, REG_MHL_EXTSTAT_0, xst, MHL_XDS_SIZE); in sii8620_msc_mr_write_stat()
1704 sii8620_update_array(ctx->stat, st, MHL_DST_SIZE); in sii8620_msc_mr_write_stat()
1705 sii8620_update_array(ctx->xstat, xst, MHL_XDS_SIZE); in sii8620_msc_mr_write_stat()
1707 if (ctx->stat[MHL_DST_CONNECTED_RDY] & st[MHL_DST_CONNECTED_RDY] & in sii8620_msc_mr_write_stat()
1709 sii8620_status_dcap_ready(ctx); in sii8620_msc_mr_write_stat()
1711 if (!sii8620_is_mhl3(ctx)) in sii8620_msc_mr_write_stat()
1712 sii8620_mt_read_devcap(ctx, false); in sii8620_msc_mr_write_stat()
1716 sii8620_status_changed_path(ctx); in sii8620_msc_mr_write_stat()
1719 static void sii8620_ecbus_up(struct sii8620 *ctx, int ret) in sii8620_ecbus_up() argument
1724 sii8620_set_mode(ctx, CM_ECBUS_S); in sii8620_ecbus_up()
1727 static void sii8620_got_ecbus_speed(struct sii8620 *ctx, int ret) in sii8620_got_ecbus_speed() argument
1732 sii8620_mt_write_stat(ctx, MHL_XDS_REG(CURR_ECBUS_MODE), in sii8620_got_ecbus_speed()
1734 sii8620_mt_rap(ctx, MHL_RAP_CBUS_MODE_UP); in sii8620_got_ecbus_speed()
1735 sii8620_mt_set_cont(ctx, sii8620_ecbus_up); in sii8620_got_ecbus_speed()
1746 static void sii8620_send_features(struct sii8620 *ctx) in sii8620_send_features() argument
1750 sii8620_write(ctx, REG_MDT_XMIT_CTRL, BIT_MDT_XMIT_CTRL_EN in sii8620_send_features()
1754 sii8620_write_buf(ctx, REG_MDT_XMIT_WRITE_PORT, buf, ARRAY_SIZE(buf)); in sii8620_send_features()
1757 static bool sii8620_rcp_consume(struct sii8620 *ctx, u8 scancode) in sii8620_rcp_consume() argument
1763 if (!IS_ENABLED(CONFIG_RC_CORE) || !ctx->rc_dev) in sii8620_rcp_consume()
1767 rc_keydown(ctx->rc_dev, RC_PROTO_CEC, scancode, 0); in sii8620_rcp_consume()
1769 rc_keyup(ctx->rc_dev); in sii8620_rcp_consume()
1774 static void sii8620_msc_mr_set_int(struct sii8620 *ctx) in sii8620_msc_mr_set_int() argument
1778 sii8620_read_buf(ctx, REG_MHL_INT_0, ints, MHL_INT_SIZE); in sii8620_msc_mr_set_int()
1779 sii8620_write_buf(ctx, REG_MHL_INT_0, ints, MHL_INT_SIZE); in sii8620_msc_mr_set_int()
1782 switch (ctx->mode) { in sii8620_msc_mr_set_int()
1784 sii8620_mt_read_xdevcap_reg(ctx, MHL_XDC_ECBUS_SPEEDS); in sii8620_msc_mr_set_int()
1785 sii8620_mt_set_cont(ctx, sii8620_got_ecbus_speed); in sii8620_msc_mr_set_int()
1788 sii8620_mt_read_devcap(ctx, true); in sii8620_msc_mr_set_int()
1795 sii8620_send_features(ctx); in sii8620_msc_mr_set_int()
1797 ctx->feature_complete = true; in sii8620_msc_mr_set_int()
1798 if (ctx->edid) in sii8620_msc_mr_set_int()
1799 sii8620_enable_hpd(ctx); in sii8620_msc_mr_set_int()
1803 static struct sii8620_mt_msg *sii8620_msc_msg_first(struct sii8620 *ctx) in sii8620_msc_msg_first() argument
1805 struct device *dev = ctx->dev; in sii8620_msc_msg_first()
1807 if (list_empty(&ctx->mt_queue)) { in sii8620_msc_msg_first()
1812 return list_first_entry(&ctx->mt_queue, struct sii8620_mt_msg, node); in sii8620_msc_msg_first()
1815 static void sii8620_msc_mt_done(struct sii8620 *ctx) in sii8620_msc_mt_done() argument
1817 struct sii8620_mt_msg *msg = sii8620_msc_msg_first(ctx); in sii8620_msc_mt_done()
1822 msg->ret = sii8620_readb(ctx, REG_MSC_MT_RCVD_DATA0); in sii8620_msc_mt_done()
1823 ctx->mt_state = MT_STATE_DONE; in sii8620_msc_mt_done()
1826 static void sii8620_msc_mr_msc_msg(struct sii8620 *ctx) in sii8620_msc_mr_msc_msg() argument
1831 sii8620_read_buf(ctx, REG_MSC_MR_MSC_MSG_RCVD_1ST_DATA, buf, 2); in sii8620_msc_mr_msc_msg()
1835 msg = sii8620_msc_msg_first(ctx); in sii8620_msc_mr_msc_msg()
1839 ctx->mt_state = MT_STATE_DONE; in sii8620_msc_mr_msc_msg()
1842 if (!sii8620_rcp_consume(ctx, buf[1])) in sii8620_msc_mr_msc_msg()
1843 sii8620_mt_rcpe(ctx, in sii8620_msc_mr_msc_msg()
1845 sii8620_mt_rcpk(ctx, buf[1]); in sii8620_msc_mr_msc_msg()
1848 dev_err(ctx->dev, "%s message type %d,%d not supported", in sii8620_msc_mr_msc_msg()
1853 static void sii8620_irq_msc(struct sii8620 *ctx) in sii8620_irq_msc() argument
1855 u8 stat = sii8620_readb(ctx, REG_CBUS_INT_0); in sii8620_irq_msc()
1858 sii8620_write(ctx, REG_CBUS_INT_0, stat & ~BIT_CBUS_HPD_CHG); in sii8620_irq_msc()
1861 u8 cbus_stat = sii8620_readb(ctx, REG_CBUS_STATUS); in sii8620_irq_msc()
1863 if ((cbus_stat ^ ctx->cbus_status) & BIT_CBUS_STATUS_CBUS_HPD) { in sii8620_irq_msc()
1864 sii8620_write(ctx, REG_CBUS_INT_0, BIT_CBUS_HPD_CHG); in sii8620_irq_msc()
1869 ctx->cbus_status = cbus_stat; in sii8620_irq_msc()
1873 sii8620_msc_mr_write_stat(ctx); in sii8620_irq_msc()
1876 if (ctx->cbus_status & BIT_CBUS_STATUS_CBUS_HPD) { in sii8620_irq_msc()
1877 ctx->sink_detected = true; in sii8620_irq_msc()
1878 sii8620_identify_sink(ctx); in sii8620_irq_msc()
1880 sii8620_hpd_unplugged(ctx); in sii8620_irq_msc()
1885 sii8620_msc_mr_set_int(ctx); in sii8620_irq_msc()
1888 sii8620_msc_mt_done(ctx); in sii8620_irq_msc()
1891 sii8620_msc_mr_msc_msg(ctx); in sii8620_irq_msc()
1894 static void sii8620_irq_coc(struct sii8620 *ctx) in sii8620_irq_coc() argument
1896 u8 stat = sii8620_readb(ctx, REG_COC_INTR); in sii8620_irq_coc()
1899 u8 cstat = sii8620_readb(ctx, REG_COC_STAT_0); in sii8620_irq_coc()
1903 sii8620_write_seq_static(ctx, in sii8620_irq_coc()
1911 sii8620_write(ctx, REG_COC_INTR, stat); in sii8620_irq_coc()
1914 static void sii8620_irq_merr(struct sii8620 *ctx) in sii8620_irq_merr() argument
1916 u8 stat = sii8620_readb(ctx, REG_CBUS_INT_1); in sii8620_irq_merr()
1918 sii8620_write(ctx, REG_CBUS_INT_1, stat); in sii8620_irq_merr()
1921 static void sii8620_irq_edid(struct sii8620 *ctx) in sii8620_irq_edid() argument
1923 u8 stat = sii8620_readb(ctx, REG_INTR9); in sii8620_irq_edid()
1925 sii8620_write(ctx, REG_INTR9, stat); in sii8620_irq_edid()
1928 ctx->mt_state = MT_STATE_DONE; in sii8620_irq_edid()
1931 static void sii8620_irq_scdt(struct sii8620 *ctx) in sii8620_irq_scdt() argument
1933 u8 stat = sii8620_readb(ctx, REG_INTR5); in sii8620_irq_scdt()
1936 u8 cstat = sii8620_readb(ctx, REG_TMDS_CSTAT_P3); in sii8620_irq_scdt()
1939 sii8620_start_video(ctx); in sii8620_irq_scdt()
1942 sii8620_write(ctx, REG_INTR5, stat); in sii8620_irq_scdt()
1945 static void sii8620_got_xdevcap(struct sii8620 *ctx, int ret) in sii8620_got_xdevcap() argument
1950 sii8620_mt_read_devcap(ctx, false); in sii8620_got_xdevcap()
1953 static void sii8620_irq_tdm(struct sii8620 *ctx) in sii8620_irq_tdm() argument
1955 u8 stat = sii8620_readb(ctx, REG_TRXINTH); in sii8620_irq_tdm()
1956 u8 tdm = sii8620_readb(ctx, REG_TRXSTA2); in sii8620_irq_tdm()
1959 ctx->mode = CM_ECBUS_S; in sii8620_irq_tdm()
1960 ctx->burst.rx_ack = 0; in sii8620_irq_tdm()
1961 ctx->burst.r_size = SII8620_BURST_BUF_LEN; in sii8620_irq_tdm()
1962 sii8620_burst_tx_rbuf_info(ctx, SII8620_BURST_BUF_LEN); in sii8620_irq_tdm()
1963 sii8620_mt_read_devcap(ctx, true); in sii8620_irq_tdm()
1964 sii8620_mt_set_cont(ctx, sii8620_got_xdevcap); in sii8620_irq_tdm()
1966 sii8620_write_seq_static(ctx, in sii8620_irq_tdm()
1972 sii8620_write(ctx, REG_TRXINTH, stat); in sii8620_irq_tdm()
1975 static void sii8620_irq_block(struct sii8620 *ctx) in sii8620_irq_block() argument
1977 u8 stat = sii8620_readb(ctx, REG_EMSCINTR); in sii8620_irq_block()
1980 u8 bstat = sii8620_readb(ctx, REG_SPIBURSTSTAT); in sii8620_irq_block()
1983 sii8620_burst_receive(ctx); in sii8620_irq_block()
1986 sii8620_write(ctx, REG_EMSCINTR, stat); in sii8620_irq_block()
1989 static void sii8620_irq_ddc(struct sii8620 *ctx) in sii8620_irq_ddc() argument
1991 u8 stat = sii8620_readb(ctx, REG_INTR3); in sii8620_irq_ddc()
1994 sii8620_write(ctx, REG_INTR3_MASK, 0); in sii8620_irq_ddc()
1995 if (sii8620_is_mhl3(ctx) && !ctx->feature_complete) in sii8620_irq_ddc()
1996 sii8620_mt_set_int(ctx, MHL_INT_REG(RCHANGE), in sii8620_irq_ddc()
1999 sii8620_enable_hpd(ctx); in sii8620_irq_ddc()
2001 sii8620_write(ctx, REG_INTR3, stat); in sii8620_irq_ddc()
2014 void (*handler)(struct sii8620 *ctx); in sii8620_irq_thread()
2027 struct sii8620 *ctx = data; in sii8620_irq_thread() local
2031 mutex_lock(&ctx->lock); in sii8620_irq_thread()
2033 sii8620_read_buf(ctx, REG_FAST_INTR_STAT, stats, ARRAY_SIZE(stats)); in sii8620_irq_thread()
2036 irq_vec[i].handler(ctx); in sii8620_irq_thread()
2038 sii8620_burst_rx_all(ctx); in sii8620_irq_thread()
2039 sii8620_mt_work(ctx); in sii8620_irq_thread()
2040 sii8620_burst_send(ctx); in sii8620_irq_thread()
2042 ret = sii8620_clear_error(ctx); in sii8620_irq_thread()
2044 dev_err(ctx->dev, "Error during IRQ handling, %d.\n", ret); in sii8620_irq_thread()
2045 sii8620_mhl_disconnected(ctx); in sii8620_irq_thread()
2047 mutex_unlock(&ctx->lock); in sii8620_irq_thread()
2052 static void sii8620_cable_in(struct sii8620 *ctx) in sii8620_cable_in() argument
2054 struct device *dev = ctx->dev; in sii8620_cable_in()
2058 ret = sii8620_hw_on(ctx); in sii8620_cable_in()
2064 sii8620_read_buf(ctx, REG_VND_IDL, ver, ARRAY_SIZE(ver)); in sii8620_cable_in()
2065 ret = sii8620_clear_error(ctx); in sii8620_cable_in()
2074 sii8620_write(ctx, REG_DPD, in sii8620_cable_in()
2077 sii8620_xtal_set_rate(ctx); in sii8620_cable_in()
2078 sii8620_disconnect(ctx); in sii8620_cable_in()
2080 sii8620_write_seq_static(ctx, in sii8620_cable_in()
2087 ret = sii8620_clear_error(ctx); in sii8620_cable_in()
2093 enable_irq(to_i2c_client(ctx->dev)->irq); in sii8620_cable_in()
2096 static void sii8620_init_rcp_input_dev(struct sii8620 *ctx) in sii8620_init_rcp_input_dev() argument
2106 dev_err(ctx->dev, "Failed to allocate RC device\n"); in sii8620_init_rcp_input_dev()
2107 ctx->error = -ENOMEM; in sii8620_init_rcp_input_dev()
2121 dev_err(ctx->dev, "Failed to register RC device\n"); in sii8620_init_rcp_input_dev()
2122 ctx->error = ret; in sii8620_init_rcp_input_dev()
2126 ctx->rc_dev = rc_dev; in sii8620_init_rcp_input_dev()
2129 static void sii8620_cable_out(struct sii8620 *ctx) in sii8620_cable_out() argument
2131 disable_irq(to_i2c_client(ctx->dev)->irq); in sii8620_cable_out()
2132 sii8620_hw_off(ctx); in sii8620_cable_out()
2137 struct sii8620 *ctx = in sii8620_extcon_work() local
2139 int state = extcon_get_state(ctx->extcon, EXTCON_DISP_MHL); in sii8620_extcon_work()
2141 if (state == ctx->cable_state) in sii8620_extcon_work()
2144 ctx->cable_state = state; in sii8620_extcon_work()
2147 sii8620_cable_in(ctx); in sii8620_extcon_work()
2149 sii8620_cable_out(ctx); in sii8620_extcon_work()
2155 struct sii8620 *ctx = in sii8620_extcon_notifier() local
2158 schedule_work(&ctx->extcon_wq); in sii8620_extcon_notifier()
2163 static int sii8620_extcon_init(struct sii8620 *ctx) in sii8620_extcon_init() argument
2170 musb = of_graph_get_remote_node(ctx->dev->of_node, 1, -1); in sii8620_extcon_init()
2175 dev_info(ctx->dev, "no extcon found, switching to 'always on' mode\n"); in sii8620_extcon_init()
2184 dev_err(ctx->dev, "Invalid or missing extcon\n"); in sii8620_extcon_init()
2188 ctx->extcon = edev; in sii8620_extcon_init()
2189 ctx->extcon_nb.notifier_call = sii8620_extcon_notifier; in sii8620_extcon_init()
2190 INIT_WORK(&ctx->extcon_wq, sii8620_extcon_work); in sii8620_extcon_init()
2191 ret = extcon_register_notifier(edev, EXTCON_DISP_MHL, &ctx->extcon_nb); in sii8620_extcon_init()
2193 dev_err(ctx->dev, "failed to register notifier for MHL\n"); in sii8620_extcon_init()
2208 struct sii8620 *ctx = bridge_to_sii8620(bridge); in sii8620_attach() local
2210 sii8620_init_rcp_input_dev(ctx); in sii8620_attach()
2212 return sii8620_clear_error(ctx); in sii8620_attach()
2217 struct sii8620 *ctx = bridge_to_sii8620(bridge); in sii8620_detach() local
2222 rc_unregister_device(ctx->rc_dev); in sii8620_detach()
2225 static int sii8620_is_packing_required(struct sii8620 *ctx, in sii8620_is_packing_required() argument
2230 if (sii8620_is_mhl3(ctx)) { in sii8620_is_packing_required()
2250 struct sii8620 *ctx = bridge_to_sii8620(bridge); in sii8620_mode_valid() local
2251 int pack_required = sii8620_is_packing_required(ctx, mode); in sii8620_mode_valid()
2252 bool can_pack = ctx->devcap[MHL_DCAP_VID_LINK_MODE] & in sii8620_mode_valid()
2269 struct sii8620 *ctx = bridge_to_sii8620(bridge); in sii8620_mode_fixup() local
2271 mutex_lock(&ctx->lock); in sii8620_mode_fixup()
2273 ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode); in sii8620_mode_fixup()
2275 mutex_unlock(&ctx->lock); in sii8620_mode_fixup()
2290 struct sii8620 *ctx; in sii8620_probe() local
2293 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); in sii8620_probe()
2294 if (!ctx) in sii8620_probe()
2297 ctx->dev = dev; in sii8620_probe()
2298 mutex_init(&ctx->lock); in sii8620_probe()
2299 INIT_LIST_HEAD(&ctx->mt_queue); in sii8620_probe()
2301 ctx->clk_xtal = devm_clk_get(dev, "xtal"); in sii8620_probe()
2302 if (IS_ERR(ctx->clk_xtal)) in sii8620_probe()
2303 return dev_err_probe(dev, PTR_ERR(ctx->clk_xtal), in sii8620_probe()
2314 "sii8620", ctx); in sii8620_probe()
2319 ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); in sii8620_probe()
2320 if (IS_ERR(ctx->gpio_reset)) in sii8620_probe()
2321 return dev_err_probe(dev, PTR_ERR(ctx->gpio_reset), in sii8620_probe()
2324 ctx->supplies[0].supply = "cvcc10"; in sii8620_probe()
2325 ctx->supplies[1].supply = "iovcc18"; in sii8620_probe()
2326 ret = devm_regulator_bulk_get(dev, 2, ctx->supplies); in sii8620_probe()
2330 ret = sii8620_extcon_init(ctx); in sii8620_probe()
2332 dev_err(ctx->dev, "failed to initialize EXTCON\n"); in sii8620_probe()
2336 i2c_set_clientdata(client, ctx); in sii8620_probe()
2338 ctx->bridge.funcs = &sii8620_bridge_funcs; in sii8620_probe()
2339 ctx->bridge.of_node = dev->of_node; in sii8620_probe()
2340 drm_bridge_add(&ctx->bridge); in sii8620_probe()
2342 if (!ctx->extcon) in sii8620_probe()
2343 sii8620_cable_in(ctx); in sii8620_probe()
2350 struct sii8620 *ctx = i2c_get_clientdata(client); in sii8620_remove() local
2352 if (ctx->extcon) { in sii8620_remove()
2353 extcon_unregister_notifier(ctx->extcon, EXTCON_DISP_MHL, in sii8620_remove()
2354 &ctx->extcon_nb); in sii8620_remove()
2355 flush_work(&ctx->extcon_wq); in sii8620_remove()
2356 if (ctx->cable_state > 0) in sii8620_remove()
2357 sii8620_cable_out(ctx); in sii8620_remove()
2359 sii8620_cable_out(ctx); in sii8620_remove()
2361 drm_bridge_remove(&ctx->bridge); in sii8620_remove()