1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (C) STMicroelectronics SA 2017
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
17 #include <media/cec.h>
19 #define CEC_NAME "stm32-cec"
22 #define CEC_CR 0x0000 /* Control Register */
23 #define CEC_CFGR 0x0004 /* ConFiGuration Register */
24 #define CEC_TXDR 0x0008 /* Rx data Register */
25 #define CEC_RXDR 0x000C /* Rx data Register */
26 #define CEC_ISR 0x0010 /* Interrupt and status Register */
27 #define CEC_IER 0x0014 /* Interrupt enable Register */
34 #define OAR GENMASK(30, 16)
36 #define BRDNOGEN BIT(7)
37 #define LBPEGEN BIT(6)
41 #define SFT GENMASK(2, 0)
42 #define FULL_CFG (LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
45 #define TXACKE BIT(12)
56 #define ALL_TX_IT (TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
57 #define ALL_RX_IT (RXEND | RXBR | RXACKE | RXOVR)
60 struct cec_adapter
*adap
;
63 struct clk
*clk_hdmi_cec
;
64 struct reset_control
*rstc
;
65 struct regmap
*regmap
;
68 struct cec_msg rx_msg
;
69 struct cec_msg tx_msg
;
73 static void cec_hw_init(struct stm32_cec
*cec
)
75 regmap_update_bits(cec
->regmap
, CEC_CR
, TXEOM
| TXSOM
| CECEN
, 0);
77 regmap_update_bits(cec
->regmap
, CEC_IER
, ALL_TX_IT
| ALL_RX_IT
,
78 ALL_TX_IT
| ALL_RX_IT
);
80 regmap_update_bits(cec
->regmap
, CEC_CFGR
, FULL_CFG
, FULL_CFG
);
83 static void stm32_tx_done(struct stm32_cec
*cec
, u32 status
)
85 if (status
& (TXERR
| TXUDR
)) {
86 cec_transmit_done(cec
->adap
, CEC_TX_STATUS_ERROR
,
91 if (status
& ARBLST
) {
92 cec_transmit_done(cec
->adap
, CEC_TX_STATUS_ARB_LOST
,
97 if (status
& TXACKE
) {
98 cec_transmit_done(cec
->adap
, CEC_TX_STATUS_NACK
,
103 if (cec
->irq_status
& TXBR
) {
105 if (cec
->tx_cnt
< cec
->tx_msg
.len
)
106 regmap_write(cec
->regmap
, CEC_TXDR
,
107 cec
->tx_msg
.msg
[cec
->tx_cnt
++]);
109 /* TXEOM is set to command transmission of the last byte */
110 if (cec
->tx_cnt
== cec
->tx_msg
.len
)
111 regmap_update_bits(cec
->regmap
, CEC_CR
, TXEOM
, TXEOM
);
114 if (cec
->irq_status
& TXEND
)
115 cec_transmit_done(cec
->adap
, CEC_TX_STATUS_OK
, 0, 0, 0, 0);
118 static void stm32_rx_done(struct stm32_cec
*cec
, u32 status
)
120 if (cec
->irq_status
& (RXACKE
| RXOVR
)) {
125 if (cec
->irq_status
& RXBR
) {
128 regmap_read(cec
->regmap
, CEC_RXDR
, &val
);
129 cec
->rx_msg
.msg
[cec
->rx_msg
.len
++] = val
& 0xFF;
132 if (cec
->irq_status
& RXEND
) {
133 cec_received_msg(cec
->adap
, &cec
->rx_msg
);
138 static irqreturn_t
stm32_cec_irq_thread(int irq
, void *arg
)
140 struct stm32_cec
*cec
= arg
;
142 if (cec
->irq_status
& ALL_TX_IT
)
143 stm32_tx_done(cec
, cec
->irq_status
);
145 if (cec
->irq_status
& ALL_RX_IT
)
146 stm32_rx_done(cec
, cec
->irq_status
);
153 static irqreturn_t
stm32_cec_irq_handler(int irq
, void *arg
)
155 struct stm32_cec
*cec
= arg
;
157 regmap_read(cec
->regmap
, CEC_ISR
, &cec
->irq_status
);
159 regmap_update_bits(cec
->regmap
, CEC_ISR
,
160 ALL_TX_IT
| ALL_RX_IT
,
161 ALL_TX_IT
| ALL_RX_IT
);
163 return IRQ_WAKE_THREAD
;
166 static int stm32_cec_adap_enable(struct cec_adapter
*adap
, bool enable
)
168 struct stm32_cec
*cec
= adap
->priv
;
172 ret
= clk_enable(cec
->clk_cec
);
174 dev_err(cec
->dev
, "fail to enable cec clock\n");
176 clk_enable(cec
->clk_hdmi_cec
);
177 regmap_update_bits(cec
->regmap
, CEC_CR
, CECEN
, CECEN
);
179 clk_disable(cec
->clk_cec
);
180 clk_disable(cec
->clk_hdmi_cec
);
181 regmap_update_bits(cec
->regmap
, CEC_CR
, CECEN
, 0);
187 static int stm32_cec_adap_log_addr(struct cec_adapter
*adap
, u8 logical_addr
)
189 struct stm32_cec
*cec
= adap
->priv
;
190 u32 oar
= (1 << logical_addr
) << 16;
192 regmap_update_bits(cec
->regmap
, CEC_CR
, CECEN
, 0);
194 if (logical_addr
== CEC_LOG_ADDR_INVALID
)
195 regmap_update_bits(cec
->regmap
, CEC_CFGR
, OAR
, 0);
197 regmap_update_bits(cec
->regmap
, CEC_CFGR
, oar
, oar
);
199 regmap_update_bits(cec
->regmap
, CEC_CR
, CECEN
, CECEN
);
204 static int stm32_cec_adap_transmit(struct cec_adapter
*adap
, u8 attempts
,
205 u32 signal_free_time
, struct cec_msg
*msg
)
207 struct stm32_cec
*cec
= adap
->priv
;
214 * If the CEC message consists of only one byte,
215 * TXEOM must be set before of TXSOM.
217 if (cec
->tx_msg
.len
== 1)
218 regmap_update_bits(cec
->regmap
, CEC_CR
, TXEOM
, TXEOM
);
220 /* TXSOM is set to command transmission of the first byte */
221 regmap_update_bits(cec
->regmap
, CEC_CR
, TXSOM
, TXSOM
);
223 /* Write the header (first byte of message) */
224 regmap_write(cec
->regmap
, CEC_TXDR
, cec
->tx_msg
.msg
[0]);
230 static const struct cec_adap_ops stm32_cec_adap_ops
= {
231 .adap_enable
= stm32_cec_adap_enable
,
232 .adap_log_addr
= stm32_cec_adap_log_addr
,
233 .adap_transmit
= stm32_cec_adap_transmit
,
236 static const struct regmap_config stm32_cec_regmap_cfg
= {
239 .reg_stride
= sizeof(u32
),
240 .max_register
= 0x14,
244 static int stm32_cec_probe(struct platform_device
*pdev
)
246 u32 caps
= CEC_CAP_DEFAULTS
| CEC_CAP_PHYS_ADDR
| CEC_MODE_MONITOR_ALL
;
247 struct resource
*res
;
248 struct stm32_cec
*cec
;
252 cec
= devm_kzalloc(&pdev
->dev
, sizeof(*cec
), GFP_KERNEL
);
256 cec
->dev
= &pdev
->dev
;
258 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
259 mmio
= devm_ioremap_resource(&pdev
->dev
, res
);
261 return PTR_ERR(mmio
);
263 cec
->regmap
= devm_regmap_init_mmio_clk(&pdev
->dev
, "cec", mmio
,
264 &stm32_cec_regmap_cfg
);
266 if (IS_ERR(cec
->regmap
))
267 return PTR_ERR(cec
->regmap
);
269 cec
->irq
= platform_get_irq(pdev
, 0);
273 ret
= devm_request_threaded_irq(&pdev
->dev
, cec
->irq
,
274 stm32_cec_irq_handler
,
275 stm32_cec_irq_thread
,
281 cec
->clk_cec
= devm_clk_get(&pdev
->dev
, "cec");
282 if (IS_ERR(cec
->clk_cec
)) {
283 dev_err(&pdev
->dev
, "Cannot get cec clock\n");
284 return PTR_ERR(cec
->clk_cec
);
287 ret
= clk_prepare(cec
->clk_cec
);
289 dev_err(&pdev
->dev
, "Unable to prepare cec clock\n");
293 cec
->clk_hdmi_cec
= devm_clk_get(&pdev
->dev
, "hdmi-cec");
294 if (!IS_ERR(cec
->clk_hdmi_cec
)) {
295 ret
= clk_prepare(cec
->clk_hdmi_cec
);
297 dev_err(&pdev
->dev
, "Unable to prepare hdmi-cec clock\n");
303 * CEC_CAP_PHYS_ADDR caps should be removed when a cec notifier is
304 * available for example when a drm driver can provide edid
306 cec
->adap
= cec_allocate_adapter(&stm32_cec_adap_ops
, cec
,
307 CEC_NAME
, caps
, CEC_MAX_LOG_ADDRS
);
308 ret
= PTR_ERR_OR_ZERO(cec
->adap
);
312 ret
= cec_register_adapter(cec
->adap
, &pdev
->dev
);
314 cec_delete_adapter(cec
->adap
);
320 platform_set_drvdata(pdev
, cec
);
325 static int stm32_cec_remove(struct platform_device
*pdev
)
327 struct stm32_cec
*cec
= platform_get_drvdata(pdev
);
329 clk_unprepare(cec
->clk_cec
);
330 clk_unprepare(cec
->clk_hdmi_cec
);
332 cec_unregister_adapter(cec
->adap
);
337 static const struct of_device_id stm32_cec_of_match
[] = {
338 { .compatible
= "st,stm32-cec" },
341 MODULE_DEVICE_TABLE(of
, stm32_cec_of_match
);
343 static struct platform_driver stm32_cec_driver
= {
344 .probe
= stm32_cec_probe
,
345 .remove
= stm32_cec_remove
,
348 .of_match_table
= stm32_cec_of_match
,
352 module_platform_driver(stm32_cec_driver
);
354 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
355 MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
356 MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
357 MODULE_LICENSE("GPL v2");