/* * 400 ms is the time it takes for one 16 byte message to be * transferred and 5 is the maximum number of retries. Add * another 100 ms as a margin.
*/ #define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
if (cec->irq_status & TXBR) { /* send next byte */ if (cec->tx_cnt < cec->tx_msg.len)
regmap_write(cec->regmap, CEC_TXDR,
cec->tx_msg.msg[cec->tx_cnt++]);
/* TXEOM is set to command transmission of the last byte */ if (cec->tx_cnt == cec->tx_msg.len)
regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
}
/* * If the CEC message consists of only one byte, * TXEOM must be set before of TXSOM.
*/ if (cec->tx_msg.len == 1)
regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
/* TXSOM is set to command transmission of the first byte */
regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
/* Write the header (first byte of message) */
regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg.msg[0]);
cec->tx_cnt++;
if (IS_ERR(cec->regmap)) return PTR_ERR(cec->regmap);
cec->irq = platform_get_irq(pdev, 0); if (cec->irq < 0) return cec->irq;
ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
stm32_cec_irq_handler,
stm32_cec_irq_thread,
0,
pdev->name, cec); if (ret) return ret;
cec->clk_cec = devm_clk_get(&pdev->dev, "cec"); if (IS_ERR(cec->clk_cec)) return dev_err_probe(&pdev->dev, PTR_ERR(cec->clk_cec), "Cannot get cec clock\n");
ret = clk_prepare(cec->clk_cec); if (ret) {
dev_err(&pdev->dev, "Unable to prepare cec clock\n"); return ret;
}
cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec"); if (IS_ERR(cec->clk_hdmi_cec) &&
PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER; goto err_unprepare_cec_clk;
}
if (!IS_ERR(cec->clk_hdmi_cec)) {
ret = clk_prepare(cec->clk_hdmi_cec); if (ret) {
dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n"); goto err_unprepare_cec_clk;
}
}
/* * CEC_CAP_PHYS_ADDR caps should be removed when a cec notifier is * available for example when a drm driver can provide edid
*/
cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
CEC_NAME, caps, CEC_MAX_LOG_ADDRS);
ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) goto err_unprepare_hdmi_cec_clk;
ret = cec_register_adapter(cec->adap, &pdev->dev); if (ret) goto err_delete_adapter;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.