1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * STM32 CEC driver
4  * Copyright (C) STMicroelectronics SA 2017
5  *
6  */
7 
8 #include <linux/clk.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 
16 #include <media/cec.h>
17 
18 #define CEC_NAME	"stm32-cec"
19 
20 /* CEC registers  */
21 #define CEC_CR		0x0000 /* Control Register */
22 #define CEC_CFGR	0x0004 /* ConFiGuration Register */
23 #define CEC_TXDR	0x0008 /* Rx data Register */
24 #define CEC_RXDR	0x000C /* Rx data Register */
25 #define CEC_ISR		0x0010 /* Interrupt and status Register */
26 #define CEC_IER		0x0014 /* Interrupt enable Register */
27 
28 #define TXEOM		BIT(2)
29 #define TXSOM		BIT(1)
30 #define CECEN		BIT(0)
31 
32 #define LSTN		BIT(31)
33 #define OAR		GENMASK(30, 16)
34 #define SFTOP		BIT(8)
35 #define BRDNOGEN	BIT(7)
36 #define LBPEGEN		BIT(6)
37 #define BREGEN		BIT(5)
38 #define BRESTP		BIT(4)
39 #define RXTOL		BIT(3)
40 #define SFT		GENMASK(2, 0)
41 #define FULL_CFG	(LSTN | SFTOP | BRDNOGEN | LBPEGEN | BREGEN | BRESTP \
42 			 | RXTOL)
43 
44 #define TXACKE		BIT(12)
45 #define TXERR		BIT(11)
46 #define TXUDR		BIT(10)
47 #define TXEND		BIT(9)
48 #define TXBR		BIT(8)
49 #define ARBLST		BIT(7)
50 #define RXACKE		BIT(6)
51 #define RXOVR		BIT(2)
52 #define RXEND		BIT(1)
53 #define RXBR		BIT(0)
54 
55 #define ALL_TX_IT	(TXEND | TXBR | TXACKE | TXERR | TXUDR | ARBLST)
56 #define ALL_RX_IT	(RXEND | RXBR | RXACKE | RXOVR)
57 
58 /*
59  * 400 ms is the time it takes for one 16 byte message to be
60  * transferred and 5 is the maximum number of retries. Add
61  * another 100 ms as a margin.
62  */
63 #define CEC_XFER_TIMEOUT_MS (5 * 400 + 100)
64 
65 struct stm32_cec {
66 	struct cec_adapter	*adap;
67 	struct device		*dev;
68 	struct clk		*clk_cec;
69 	struct clk		*clk_hdmi_cec;
70 	struct reset_control	*rstc;
71 	struct regmap		*regmap;
72 	int			irq;
73 	u32			irq_status;
74 	struct cec_msg		rx_msg;
75 	struct cec_msg		tx_msg;
76 	int			tx_cnt;
77 };
78 
79 static void cec_hw_init(struct stm32_cec *cec)
80 {
81 	regmap_update_bits(cec->regmap, CEC_CR, TXEOM | TXSOM | CECEN, 0);
82 
83 	regmap_update_bits(cec->regmap, CEC_IER, ALL_TX_IT | ALL_RX_IT,
84 			   ALL_TX_IT | ALL_RX_IT);
85 
86 	regmap_update_bits(cec->regmap, CEC_CFGR, FULL_CFG, FULL_CFG);
87 }
88 
89 static void stm32_tx_done(struct stm32_cec *cec, u32 status)
90 {
91 	if (status & (TXERR | TXUDR)) {
92 		cec_transmit_done(cec->adap, CEC_TX_STATUS_ERROR,
93 				  0, 0, 0, 1);
94 		return;
95 	}
96 
97 	if (status & ARBLST) {
98 		cec_transmit_done(cec->adap, CEC_TX_STATUS_ARB_LOST,
99 				  1, 0, 0, 0);
100 		return;
101 	}
102 
103 	if (status & TXACKE) {
104 		cec_transmit_done(cec->adap, CEC_TX_STATUS_NACK,
105 				  0, 1, 0, 0);
106 		return;
107 	}
108 
109 	if (cec->irq_status & TXBR) {
110 		/* send next byte */
111 		if (cec->tx_cnt < cec->tx_msg.len)
112 			regmap_write(cec->regmap, CEC_TXDR,
113 				     cec->tx_msg.msg[cec->tx_cnt++]);
114 
115 		/* TXEOM is set to command transmission of the last byte */
116 		if (cec->tx_cnt == cec->tx_msg.len)
117 			regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
118 	}
119 
120 	if (cec->irq_status & TXEND)
121 		cec_transmit_done(cec->adap, CEC_TX_STATUS_OK, 0, 0, 0, 0);
122 }
123 
124 static void stm32_rx_done(struct stm32_cec *cec, u32 status)
125 {
126 	if (cec->irq_status & (RXACKE | RXOVR)) {
127 		cec->rx_msg.len = 0;
128 		return;
129 	}
130 
131 	if (cec->irq_status & RXBR) {
132 		u32 val;
133 
134 		regmap_read(cec->regmap, CEC_RXDR, &val);
135 		cec->rx_msg.msg[cec->rx_msg.len++] = val & 0xFF;
136 	}
137 
138 	if (cec->irq_status & RXEND) {
139 		cec_received_msg(cec->adap, &cec->rx_msg);
140 		cec->rx_msg.len = 0;
141 	}
142 }
143 
144 static irqreturn_t stm32_cec_irq_thread(int irq, void *arg)
145 {
146 	struct stm32_cec *cec = arg;
147 
148 	if (cec->irq_status & ALL_TX_IT)
149 		stm32_tx_done(cec, cec->irq_status);
150 
151 	if (cec->irq_status & ALL_RX_IT)
152 		stm32_rx_done(cec, cec->irq_status);
153 
154 	cec->irq_status = 0;
155 
156 	return IRQ_HANDLED;
157 }
158 
159 static irqreturn_t stm32_cec_irq_handler(int irq, void *arg)
160 {
161 	struct stm32_cec *cec = arg;
162 
163 	regmap_read(cec->regmap, CEC_ISR, &cec->irq_status);
164 
165 	regmap_update_bits(cec->regmap, CEC_ISR,
166 			   ALL_TX_IT | ALL_RX_IT,
167 			   ALL_TX_IT | ALL_RX_IT);
168 
169 	return IRQ_WAKE_THREAD;
170 }
171 
172 static int stm32_cec_adap_enable(struct cec_adapter *adap, bool enable)
173 {
174 	struct stm32_cec *cec = adap->priv;
175 	int ret = 0;
176 
177 	if (enable) {
178 		ret = clk_enable(cec->clk_cec);
179 		if (ret)
180 			dev_err(cec->dev, "fail to enable cec clock\n");
181 
182 		clk_enable(cec->clk_hdmi_cec);
183 		regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
184 	} else {
185 		clk_disable(cec->clk_cec);
186 		clk_disable(cec->clk_hdmi_cec);
187 		regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
188 	}
189 
190 	return ret;
191 }
192 
193 static int stm32_cec_adap_log_addr(struct cec_adapter *adap, u8 logical_addr)
194 {
195 	struct stm32_cec *cec = adap->priv;
196 	u32 oar = (1 << logical_addr) << 16;
197 	u32 val;
198 
199 	/* Poll every 100µs the register CEC_CR to wait end of transmission */
200 	regmap_read_poll_timeout(cec->regmap, CEC_CR, val, !(val & TXSOM),
201 				 100, CEC_XFER_TIMEOUT_MS * 1000);
202 	regmap_update_bits(cec->regmap, CEC_CR, CECEN, 0);
203 
204 	if (logical_addr == CEC_LOG_ADDR_INVALID)
205 		regmap_update_bits(cec->regmap, CEC_CFGR, OAR, 0);
206 	else
207 		regmap_update_bits(cec->regmap, CEC_CFGR, oar, oar);
208 
209 	regmap_update_bits(cec->regmap, CEC_CR, CECEN, CECEN);
210 
211 	return 0;
212 }
213 
214 static int stm32_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
215 				   u32 signal_free_time, struct cec_msg *msg)
216 {
217 	struct stm32_cec *cec = adap->priv;
218 
219 	/* Copy message */
220 	cec->tx_msg = *msg;
221 	cec->tx_cnt = 0;
222 
223 	/*
224 	 * If the CEC message consists of only one byte,
225 	 * TXEOM must be set before of TXSOM.
226 	 */
227 	if (cec->tx_msg.len == 1)
228 		regmap_update_bits(cec->regmap, CEC_CR, TXEOM, TXEOM);
229 
230 	/* TXSOM is set to command transmission of the first byte */
231 	regmap_update_bits(cec->regmap, CEC_CR, TXSOM, TXSOM);
232 
233 	/* Write the header (first byte of message) */
234 	regmap_write(cec->regmap, CEC_TXDR, cec->tx_msg.msg[0]);
235 	cec->tx_cnt++;
236 
237 	return 0;
238 }
239 
240 static const struct cec_adap_ops stm32_cec_adap_ops = {
241 	.adap_enable = stm32_cec_adap_enable,
242 	.adap_log_addr = stm32_cec_adap_log_addr,
243 	.adap_transmit = stm32_cec_adap_transmit,
244 };
245 
246 static const struct regmap_config stm32_cec_regmap_cfg = {
247 	.reg_bits = 32,
248 	.val_bits = 32,
249 	.reg_stride = sizeof(u32),
250 	.max_register = 0x14,
251 	.fast_io = true,
252 };
253 
254 static int stm32_cec_probe(struct platform_device *pdev)
255 {
256 	u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR | CEC_MODE_MONITOR_ALL;
257 	struct stm32_cec *cec;
258 	void __iomem *mmio;
259 	int ret;
260 
261 	cec = devm_kzalloc(&pdev->dev, sizeof(*cec), GFP_KERNEL);
262 	if (!cec)
263 		return -ENOMEM;
264 
265 	cec->dev = &pdev->dev;
266 
267 	mmio = devm_platform_ioremap_resource(pdev, 0);
268 	if (IS_ERR(mmio))
269 		return PTR_ERR(mmio);
270 
271 	cec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "cec", mmio,
272 						&stm32_cec_regmap_cfg);
273 
274 	if (IS_ERR(cec->regmap))
275 		return PTR_ERR(cec->regmap);
276 
277 	cec->irq = platform_get_irq(pdev, 0);
278 	if (cec->irq < 0)
279 		return cec->irq;
280 
281 	ret = devm_request_threaded_irq(&pdev->dev, cec->irq,
282 					stm32_cec_irq_handler,
283 					stm32_cec_irq_thread,
284 					0,
285 					pdev->name, cec);
286 	if (ret)
287 		return ret;
288 
289 	cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
290 	if (IS_ERR(cec->clk_cec))
291 		return dev_err_probe(&pdev->dev, PTR_ERR(cec->clk_cec),
292 				     "Cannot get cec clock\n");
293 
294 	ret = clk_prepare(cec->clk_cec);
295 	if (ret) {
296 		dev_err(&pdev->dev, "Unable to prepare cec clock\n");
297 		return ret;
298 	}
299 
300 	cec->clk_hdmi_cec = devm_clk_get(&pdev->dev, "hdmi-cec");
301 	if (IS_ERR(cec->clk_hdmi_cec) &&
302 	    PTR_ERR(cec->clk_hdmi_cec) == -EPROBE_DEFER) {
303 		ret = -EPROBE_DEFER;
304 		goto err_unprepare_cec_clk;
305 	}
306 
307 	if (!IS_ERR(cec->clk_hdmi_cec)) {
308 		ret = clk_prepare(cec->clk_hdmi_cec);
309 		if (ret) {
310 			dev_err(&pdev->dev, "Can't prepare hdmi-cec clock\n");
311 			goto err_unprepare_cec_clk;
312 		}
313 	}
314 
315 	/*
316 	 * CEC_CAP_PHYS_ADDR caps should be removed when a cec notifier is
317 	 * available for example when a drm driver can provide edid
318 	 */
319 	cec->adap = cec_allocate_adapter(&stm32_cec_adap_ops, cec,
320 			CEC_NAME, caps,	CEC_MAX_LOG_ADDRS);
321 	ret = PTR_ERR_OR_ZERO(cec->adap);
322 	if (ret)
323 		goto err_unprepare_hdmi_cec_clk;
324 
325 	ret = cec_register_adapter(cec->adap, &pdev->dev);
326 	if (ret)
327 		goto err_delete_adapter;
328 
329 	cec_hw_init(cec);
330 
331 	platform_set_drvdata(pdev, cec);
332 
333 	return 0;
334 
335 err_delete_adapter:
336 	cec_delete_adapter(cec->adap);
337 
338 err_unprepare_hdmi_cec_clk:
339 	clk_unprepare(cec->clk_hdmi_cec);
340 
341 err_unprepare_cec_clk:
342 	clk_unprepare(cec->clk_cec);
343 	return ret;
344 }
345 
346 static void stm32_cec_remove(struct platform_device *pdev)
347 {
348 	struct stm32_cec *cec = platform_get_drvdata(pdev);
349 
350 	clk_unprepare(cec->clk_cec);
351 	clk_unprepare(cec->clk_hdmi_cec);
352 
353 	cec_unregister_adapter(cec->adap);
354 }
355 
356 static const struct of_device_id stm32_cec_of_match[] = {
357 	{ .compatible = "st,stm32-cec" },
358 	{ /* end node */ }
359 };
360 MODULE_DEVICE_TABLE(of, stm32_cec_of_match);
361 
362 static struct platform_driver stm32_cec_driver = {
363 	.probe  = stm32_cec_probe,
364 	.remove_new = stm32_cec_remove,
365 	.driver = {
366 		.name		= CEC_NAME,
367 		.of_match_table = stm32_cec_of_match,
368 	},
369 };
370 
371 module_platform_driver(stm32_cec_driver);
372 
373 MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
374 MODULE_AUTHOR("Yannick Fertre <yannick.fertre@st.com>");
375 MODULE_DESCRIPTION("STMicroelectronics STM32 Consumer Electronics Control");
376 MODULE_LICENSE("GPL v2");
377