]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/media/platform/meson/ao-cec-g12a.c
Merge tag 'v5.3-rc4' into patchwork
[linux.git] / drivers / media / platform / meson / ao-cec-g12a.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Driver for Amlogic Meson AO CEC G12A Controller
4  *
5  * Copyright (C) 2017 Amlogic, Inc. All rights reserved
6  * Copyright (C) 2019 BayLibre, SAS
7  * Author: Neil Armstrong <narmstrong@baylibre.com>
8  */
9
10 #include <linux/bitfield.h>
11 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/io.h>
14 #include <linux/delay.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/of.h>
18 #include <linux/of_platform.h>
19 #include <linux/platform_device.h>
20 #include <linux/types.h>
21 #include <linux/interrupt.h>
22 #include <linux/reset.h>
23 #include <linux/slab.h>
24 #include <linux/regmap.h>
25 #include <media/cec.h>
26 #include <media/cec-notifier.h>
27 #include <linux/clk-provider.h>
28
29 /* CEC Registers */
30
31 #define CECB_CLK_CNTL_REG0              0x00
32
33 #define CECB_CLK_CNTL_N1                GENMASK(11, 0)
34 #define CECB_CLK_CNTL_N2                GENMASK(23, 12)
35 #define CECB_CLK_CNTL_DUAL_EN           BIT(28)
36 #define CECB_CLK_CNTL_OUTPUT_EN         BIT(30)
37 #define CECB_CLK_CNTL_INPUT_EN          BIT(31)
38
39 #define CECB_CLK_CNTL_REG1              0x04
40
41 #define CECB_CLK_CNTL_M1                GENMASK(11, 0)
42 #define CECB_CLK_CNTL_M2                GENMASK(23, 12)
43 #define CECB_CLK_CNTL_BYPASS_EN         BIT(24)
44
45 /*
46  * [14:12] Filter_del. For glitch-filtering CEC line, ignore signal
47  *       change pulse width < filter_del * T(filter_tick) * 3.
48  * [9:8] Filter_tick_sel: Select which periodical pulse for
49  *       glitch-filtering CEC line signal.
50  *  - 0=Use T(xtal)*3 = 125ns;
51  *  - 1=Use once-per-1us pulse;
52  *  - 2=Use once-per-10us pulse;
53  *  - 3=Use once-per-100us pulse.
54  * [3]   Sysclk_en. 0=Disable system clock; 1=Enable system clock.
55  * [2:1] cntl_clk
56  *  - 0 = Disable clk (Power-off mode)
57  *  - 1 = Enable gated clock (Normal mode)
58  *  - 2 = Enable free-run clk (Debug mode)
59  * [0] SW_RESET 1=Apply reset; 0=No reset.
60  */
61 #define CECB_GEN_CNTL_REG               0x08
62
63 #define CECB_GEN_CNTL_RESET             BIT(0)
64 #define CECB_GEN_CNTL_CLK_DISABLE       0
65 #define CECB_GEN_CNTL_CLK_ENABLE        1
66 #define CECB_GEN_CNTL_CLK_ENABLE_DBG    2
67 #define CECB_GEN_CNTL_CLK_CTRL_MASK     GENMASK(2, 1)
68 #define CECB_GEN_CNTL_SYS_CLK_EN        BIT(3)
69 #define CECB_GEN_CNTL_FILTER_TICK_125NS 0
70 #define CECB_GEN_CNTL_FILTER_TICK_1US   1
71 #define CECB_GEN_CNTL_FILTER_TICK_10US  2
72 #define CECB_GEN_CNTL_FILTER_TICK_100US 3
73 #define CECB_GEN_CNTL_FILTER_TICK_SEL   GENMASK(9, 8)
74 #define CECB_GEN_CNTL_FILTER_DEL        GENMASK(14, 12)
75
76 /*
77  * [7:0] cec_reg_addr
78  * [15:8] cec_reg_wrdata
79  * [16] cec_reg_wr
80  *  - 0 = Read
81  *  - 1 = Write
82  * [31:24] cec_reg_rddata
83  */
84 #define CECB_RW_REG                     0x0c
85
86 #define CECB_RW_ADDR                    GENMASK(7, 0)
87 #define CECB_RW_WR_DATA                 GENMASK(15, 8)
88 #define CECB_RW_WRITE_EN                BIT(16)
89 #define CECB_RW_BUS_BUSY                BIT(23)
90 #define CECB_RW_RD_DATA                 GENMASK(31, 24)
91
92 /*
93  * [0] DONE Interrupt
94  * [1] End Of Message Interrupt
95  * [2] Not Acknowlegde Interrupt
96  * [3] Arbitration Loss Interrupt
97  * [4] Initiator Error Interrupt
98  * [5] Follower Error Interrupt
99  * [6] Wake-Up Interrupt
100  */
101 #define CECB_INTR_MASKN_REG             0x10
102 #define CECB_INTR_CLR_REG               0x14
103 #define CECB_INTR_STAT_REG              0x18
104
105 #define CECB_INTR_DONE                  BIT(0)
106 #define CECB_INTR_EOM                   BIT(1)
107 #define CECB_INTR_NACK                  BIT(2)
108 #define CECB_INTR_ARB_LOSS              BIT(3)
109 #define CECB_INTR_INITIATOR_ERR         BIT(4)
110 #define CECB_INTR_FOLLOWER_ERR          BIT(5)
111 #define CECB_INTR_WAKE_UP               BIT(6)
112
113 /* CEC Commands */
114
115 #define CECB_CTRL               0x00
116
117 #define CECB_CTRL_SEND          BIT(0)
118 #define CECB_CTRL_TYPE          GENMASK(2, 1)
119 #define CECB_CTRL_TYPE_RETRY    0
120 #define CECB_CTRL_TYPE_NEW      1
121 #define CECB_CTRL_TYPE_NEXT     2
122
123 #define CECB_CTRL2              0x01
124
125 #define CECB_CTRL2_RISE_DEL_MAX GENMASK(4, 0)
126
127 #define CECB_INTR_MASK          0x02
128 #define CECB_LADD_LOW           0x05
129 #define CECB_LADD_HIGH          0x06
130 #define CECB_TX_CNT             0x07
131 #define CECB_RX_CNT             0x08
132 #define CECB_STAT0              0x09
133 #define CECB_TX_DATA00          0x10
134 #define CECB_TX_DATA01          0x11
135 #define CECB_TX_DATA02          0x12
136 #define CECB_TX_DATA03          0x13
137 #define CECB_TX_DATA04          0x14
138 #define CECB_TX_DATA05          0x15
139 #define CECB_TX_DATA06          0x16
140 #define CECB_TX_DATA07          0x17
141 #define CECB_TX_DATA08          0x18
142 #define CECB_TX_DATA09          0x19
143 #define CECB_TX_DATA10          0x1A
144 #define CECB_TX_DATA11          0x1B
145 #define CECB_TX_DATA12          0x1C
146 #define CECB_TX_DATA13          0x1D
147 #define CECB_TX_DATA14          0x1E
148 #define CECB_TX_DATA15          0x1F
149 #define CECB_RX_DATA00          0x20
150 #define CECB_RX_DATA01          0x21
151 #define CECB_RX_DATA02          0x22
152 #define CECB_RX_DATA03          0x23
153 #define CECB_RX_DATA04          0x24
154 #define CECB_RX_DATA05          0x25
155 #define CECB_RX_DATA06          0x26
156 #define CECB_RX_DATA07          0x27
157 #define CECB_RX_DATA08          0x28
158 #define CECB_RX_DATA09          0x29
159 #define CECB_RX_DATA10          0x2A
160 #define CECB_RX_DATA11          0x2B
161 #define CECB_RX_DATA12          0x2C
162 #define CECB_RX_DATA13          0x2D
163 #define CECB_RX_DATA14          0x2E
164 #define CECB_RX_DATA15          0x2F
165 #define CECB_LOCK_BUF           0x30
166
167 #define CECB_LOCK_BUF_EN        BIT(0)
168
169 #define CECB_WAKEUPCTRL         0x31
170
171 struct meson_ao_cec_g12a_data {
172         /* Setup the internal CECB_CTRL2 register */
173         bool                            ctrl2_setup;
174 };
175
176 struct meson_ao_cec_g12a_device {
177         struct platform_device          *pdev;
178         struct regmap                   *regmap;
179         struct regmap                   *regmap_cec;
180         spinlock_t                      cec_reg_lock;
181         struct cec_notifier             *notify;
182         struct cec_adapter              *adap;
183         struct cec_msg                  rx_msg;
184         struct clk                      *oscin;
185         struct clk                      *core;
186         const struct meson_ao_cec_g12a_data *data;
187 };
188
189 static const struct regmap_config meson_ao_cec_g12a_regmap_conf = {
190         .reg_bits = 8,
191         .val_bits = 32,
192         .reg_stride = 4,
193         .max_register = CECB_INTR_STAT_REG,
194 };
195
196 /*
197  * The AO-CECB embeds a dual/divider to generate a more precise
198  * 32,768KHz clock for CEC core clock.
199  *                      ______   ______
200  *                     |      | |      |
201  *         ______      | Div1 |-| Cnt1 |       ______
202  *        |      |    /|______| |______|\     |      |
203  * Xtal-->| Gate |---|  ______   ______  X-X--| Gate |-->
204  *        |______| |  \|      | |      |/  |  |______|
205  *                 |   | Div2 |-| Cnt2 |   |
206  *                 |   |______| |______|   |
207  *                 |_______________________|
208  *
209  * The dividing can be switched to single or dual, with a counter
210  * for each divider to set when the switching is done.
211  * The entire dividing mechanism can be also bypassed.
212  */
213
214 struct meson_ao_cec_g12a_dualdiv_clk {
215         struct clk_hw hw;
216         struct regmap *regmap;
217 };
218
219 #define hw_to_meson_ao_cec_g12a_dualdiv_clk(_hw)                        \
220         container_of(_hw, struct meson_ao_cec_g12a_dualdiv_clk, hw)     \
221
222 static unsigned long
223 meson_ao_cec_g12a_dualdiv_clk_recalc_rate(struct clk_hw *hw,
224                                           unsigned long parent_rate)
225 {
226         struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
227                 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
228         unsigned long n1;
229         u32 reg0, reg1;
230
231         regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg0);
232         regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &reg1);
233
234         if (reg1 & CECB_CLK_CNTL_BYPASS_EN)
235                 return parent_rate;
236
237         if (reg0 & CECB_CLK_CNTL_DUAL_EN) {
238                 unsigned long n2, m1, m2, f1, f2, p1, p2;
239
240                 n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
241                 n2 = FIELD_GET(CECB_CLK_CNTL_N2, reg0) + 1;
242
243                 m1 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
244                 m2 = FIELD_GET(CECB_CLK_CNTL_M1, reg1) + 1;
245
246                 f1 = DIV_ROUND_CLOSEST(parent_rate, n1);
247                 f2 = DIV_ROUND_CLOSEST(parent_rate, n2);
248
249                 p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2));
250                 p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2));
251
252                 return DIV_ROUND_UP(100000000, p1 + p2);
253         }
254
255         n1 = FIELD_GET(CECB_CLK_CNTL_N1, reg0) + 1;
256
257         return DIV_ROUND_CLOSEST(parent_rate, n1);
258 }
259
260 static int meson_ao_cec_g12a_dualdiv_clk_enable(struct clk_hw *hw)
261 {
262         struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
263                 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
264
265
266         /* Disable Input & Output */
267         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
268                            CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
269                            0);
270
271         /* Set N1 & N2 */
272         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
273                            CECB_CLK_CNTL_N1,
274                            FIELD_PREP(CECB_CLK_CNTL_N1, 733 - 1));
275
276         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
277                            CECB_CLK_CNTL_N2,
278                            FIELD_PREP(CECB_CLK_CNTL_N2, 732 - 1));
279
280         /* Set M1 & M2 */
281         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
282                            CECB_CLK_CNTL_M1,
283                            FIELD_PREP(CECB_CLK_CNTL_M1, 8 - 1));
284
285         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
286                            CECB_CLK_CNTL_M2,
287                            FIELD_PREP(CECB_CLK_CNTL_M2, 11 - 1));
288
289         /* Enable Dual divisor */
290         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
291                            CECB_CLK_CNTL_DUAL_EN, CECB_CLK_CNTL_DUAL_EN);
292
293         /* Disable divisor bypass */
294         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG1,
295                            CECB_CLK_CNTL_BYPASS_EN, 0);
296
297         /* Enable Input & Output */
298         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
299                            CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
300                            CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN);
301
302         return 0;
303 }
304
305 static void meson_ao_cec_g12a_dualdiv_clk_disable(struct clk_hw *hw)
306 {
307         struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
308                 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
309
310         regmap_update_bits(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0,
311                            CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN,
312                            0);
313 }
314
315 static int meson_ao_cec_g12a_dualdiv_clk_is_enabled(struct clk_hw *hw)
316 {
317         struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk =
318                 hw_to_meson_ao_cec_g12a_dualdiv_clk(hw);
319         int val;
320
321         regmap_read(dualdiv_clk->regmap, CECB_CLK_CNTL_REG0, &val);
322
323         return !!(val & (CECB_CLK_CNTL_INPUT_EN | CECB_CLK_CNTL_OUTPUT_EN));
324 }
325
326 static const struct clk_ops meson_ao_cec_g12a_dualdiv_clk_ops = {
327         .recalc_rate    = meson_ao_cec_g12a_dualdiv_clk_recalc_rate,
328         .is_enabled     = meson_ao_cec_g12a_dualdiv_clk_is_enabled,
329         .enable         = meson_ao_cec_g12a_dualdiv_clk_enable,
330         .disable        = meson_ao_cec_g12a_dualdiv_clk_disable,
331 };
332
333 static int meson_ao_cec_g12a_setup_clk(struct meson_ao_cec_g12a_device *ao_cec)
334 {
335         struct meson_ao_cec_g12a_dualdiv_clk *dualdiv_clk;
336         struct device *dev = &ao_cec->pdev->dev;
337         struct clk_init_data init;
338         const char *parent_name;
339         struct clk *clk;
340         char *name;
341
342         dualdiv_clk = devm_kzalloc(dev, sizeof(*dualdiv_clk), GFP_KERNEL);
343         if (!dualdiv_clk)
344                 return -ENOMEM;
345
346         name = kasprintf(GFP_KERNEL, "%s#dualdiv_clk", dev_name(dev));
347         if (!name)
348                 return -ENOMEM;
349
350         parent_name = __clk_get_name(ao_cec->oscin);
351
352         init.name = name;
353         init.ops = &meson_ao_cec_g12a_dualdiv_clk_ops;
354         init.flags = 0;
355         init.parent_names = &parent_name;
356         init.num_parents = 1;
357         dualdiv_clk->regmap = ao_cec->regmap;
358         dualdiv_clk->hw.init = &init;
359
360         clk = devm_clk_register(dev, &dualdiv_clk->hw);
361         kfree(name);
362         if (IS_ERR(clk)) {
363                 dev_err(dev, "failed to register clock\n");
364                 return PTR_ERR(clk);
365         }
366
367         ao_cec->core = clk;
368
369         return 0;
370 }
371
372 static int meson_ao_cec_g12a_read(void *context, unsigned int addr,
373                                   unsigned int *data)
374 {
375         struct meson_ao_cec_g12a_device *ao_cec = context;
376         u32 reg = FIELD_PREP(CECB_RW_ADDR, addr);
377         int ret = 0;
378
379         ret = regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
380         if (ret)
381                 return ret;
382
383         ret = regmap_read_poll_timeout(ao_cec->regmap, CECB_RW_REG, reg,
384                                        !(reg & CECB_RW_BUS_BUSY),
385                                        5, 1000);
386         if (ret)
387                 return ret;
388
389         ret = regmap_read(ao_cec->regmap, CECB_RW_REG, &reg);
390
391         *data = FIELD_GET(CECB_RW_RD_DATA, reg);
392
393         return ret;
394 }
395
396 static int meson_ao_cec_g12a_write(void *context, unsigned int addr,
397                                    unsigned int data)
398 {
399         struct meson_ao_cec_g12a_device *ao_cec = context;
400         u32 reg = FIELD_PREP(CECB_RW_ADDR, addr) |
401                   FIELD_PREP(CECB_RW_WR_DATA, data) |
402                   CECB_RW_WRITE_EN;
403
404         return regmap_write(ao_cec->regmap, CECB_RW_REG, reg);
405 }
406
407 static const struct regmap_config meson_ao_cec_g12a_cec_regmap_conf = {
408         .reg_bits = 8,
409         .val_bits = 8,
410         .reg_read = meson_ao_cec_g12a_read,
411         .reg_write = meson_ao_cec_g12a_write,
412         .max_register = 0xffff,
413 };
414
415 static inline void
416 meson_ao_cec_g12a_irq_setup(struct meson_ao_cec_g12a_device *ao_cec,
417                             bool enable)
418 {
419         u32 cfg = CECB_INTR_DONE | CECB_INTR_EOM | CECB_INTR_NACK |
420                   CECB_INTR_ARB_LOSS | CECB_INTR_INITIATOR_ERR |
421                   CECB_INTR_FOLLOWER_ERR;
422
423         regmap_write(ao_cec->regmap, CECB_INTR_MASKN_REG,
424                      enable ? cfg : 0);
425 }
426
427 static void meson_ao_cec_g12a_irq_rx(struct meson_ao_cec_g12a_device *ao_cec)
428 {
429         int i, ret = 0;
430         u32 val;
431
432         ret = regmap_read(ao_cec->regmap_cec, CECB_RX_CNT, &val);
433
434         ao_cec->rx_msg.len = val;
435         if (ao_cec->rx_msg.len > CEC_MAX_MSG_SIZE)
436                 ao_cec->rx_msg.len = CEC_MAX_MSG_SIZE;
437
438         for (i = 0; i < ao_cec->rx_msg.len; i++) {
439                 ret |= regmap_read(ao_cec->regmap_cec,
440                                    CECB_RX_DATA00 + i, &val);
441
442                 ao_cec->rx_msg.msg[i] = val & 0xff;
443         }
444
445         ret |= regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
446         if (ret)
447                 return;
448
449         cec_received_msg(ao_cec->adap, &ao_cec->rx_msg);
450 }
451
452 static irqreturn_t meson_ao_cec_g12a_irq(int irq, void *data)
453 {
454         struct meson_ao_cec_g12a_device *ao_cec = data;
455         u32 stat;
456
457         regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
458         if (stat)
459                 return IRQ_WAKE_THREAD;
460
461         return IRQ_NONE;
462 }
463
464 static irqreturn_t meson_ao_cec_g12a_irq_thread(int irq, void *data)
465 {
466         struct meson_ao_cec_g12a_device *ao_cec = data;
467         u32 stat;
468
469         regmap_read(ao_cec->regmap, CECB_INTR_STAT_REG, &stat);
470         regmap_write(ao_cec->regmap, CECB_INTR_CLR_REG, stat);
471
472         if (stat & CECB_INTR_DONE)
473                 cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_OK);
474
475         if (stat & CECB_INTR_EOM)
476                 meson_ao_cec_g12a_irq_rx(ao_cec);
477
478         if (stat & CECB_INTR_NACK)
479                 cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_NACK);
480
481         if (stat & CECB_INTR_ARB_LOSS) {
482                 regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, 0);
483                 regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
484                                    CECB_CTRL_SEND | CECB_CTRL_TYPE, 0);
485                 cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ARB_LOST);
486         }
487
488         /* Initiator reports an error on the CEC bus */
489         if (stat & CECB_INTR_INITIATOR_ERR)
490                 cec_transmit_attempt_done(ao_cec->adap, CEC_TX_STATUS_ERROR);
491
492         /* Follower reports a receive error, just reset RX buffer */
493         if (stat & CECB_INTR_FOLLOWER_ERR)
494                 regmap_write(ao_cec->regmap_cec, CECB_LOCK_BUF, 0);
495
496         return IRQ_HANDLED;
497 }
498
499 static int
500 meson_ao_cec_g12a_set_log_addr(struct cec_adapter *adap, u8 logical_addr)
501 {
502         struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
503         int ret = 0;
504
505         if (logical_addr == CEC_LOG_ADDR_INVALID) {
506                 /* Assume this will allways succeed */
507                 regmap_write(ao_cec->regmap_cec, CECB_LADD_LOW, 0);
508                 regmap_write(ao_cec->regmap_cec, CECB_LADD_HIGH, 0);
509
510                 return 0;
511         } else if (logical_addr < 8) {
512                 ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_LOW,
513                                          BIT(logical_addr),
514                                          BIT(logical_addr));
515         } else {
516                 ret = regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
517                                          BIT(logical_addr - 8),
518                                          BIT(logical_addr - 8));
519         }
520
521         /* Always set Broadcast/Unregistered 15 address */
522         ret |= regmap_update_bits(ao_cec->regmap_cec, CECB_LADD_HIGH,
523                                   BIT(CEC_LOG_ADDR_UNREGISTERED - 8),
524                                   BIT(CEC_LOG_ADDR_UNREGISTERED - 8));
525
526         return ret ? -EIO : 0;
527 }
528
529 static int meson_ao_cec_g12a_transmit(struct cec_adapter *adap, u8 attempts,
530                                  u32 signal_free_time, struct cec_msg *msg)
531 {
532         struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
533         unsigned int type;
534         int ret = 0;
535         u32 val;
536         int i;
537
538         /* Check if RX is in progress */
539         ret = regmap_read(ao_cec->regmap_cec, CECB_LOCK_BUF, &val);
540         if (ret)
541                 return ret;
542         if (val & CECB_LOCK_BUF_EN)
543                 return -EBUSY;
544
545         /* Check if TX Busy */
546         ret = regmap_read(ao_cec->regmap_cec, CECB_CTRL, &val);
547         if (ret)
548                 return ret;
549         if (val & CECB_CTRL_SEND)
550                 return -EBUSY;
551
552         switch (signal_free_time) {
553         case CEC_SIGNAL_FREE_TIME_RETRY:
554                 type = CECB_CTRL_TYPE_RETRY;
555                 break;
556         case CEC_SIGNAL_FREE_TIME_NEXT_XFER:
557                 type = CECB_CTRL_TYPE_NEXT;
558                 break;
559         case CEC_SIGNAL_FREE_TIME_NEW_INITIATOR:
560         default:
561                 type = CECB_CTRL_TYPE_NEW;
562                 break;
563         }
564
565         for (i = 0; i < msg->len; i++)
566                 ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_DATA00 + i,
567                                     msg->msg[i]);
568
569         ret |= regmap_write(ao_cec->regmap_cec, CECB_TX_CNT, msg->len);
570         if (ret)
571                 return -EIO;
572
573         ret = regmap_update_bits(ao_cec->regmap_cec, CECB_CTRL,
574                                  CECB_CTRL_SEND |
575                                  CECB_CTRL_TYPE,
576                                  CECB_CTRL_SEND |
577                                  FIELD_PREP(CECB_CTRL_TYPE, type));
578
579         return ret;
580 }
581
582 static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable)
583 {
584         struct meson_ao_cec_g12a_device *ao_cec = adap->priv;
585
586         meson_ao_cec_g12a_irq_setup(ao_cec, false);
587
588         regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
589                            CECB_GEN_CNTL_RESET, CECB_GEN_CNTL_RESET);
590
591         if (!enable)
592                 return 0;
593
594         /* Setup Filter */
595         regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
596                            CECB_GEN_CNTL_FILTER_TICK_SEL |
597                            CECB_GEN_CNTL_FILTER_DEL,
598                            FIELD_PREP(CECB_GEN_CNTL_FILTER_TICK_SEL,
599                                       CECB_GEN_CNTL_FILTER_TICK_1US) |
600                            FIELD_PREP(CECB_GEN_CNTL_FILTER_DEL, 7));
601
602         /* Enable System Clock */
603         regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
604                            CECB_GEN_CNTL_SYS_CLK_EN,
605                            CECB_GEN_CNTL_SYS_CLK_EN);
606
607         /* Enable gated clock (Normal mode). */
608         regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
609                            CECB_GEN_CNTL_CLK_CTRL_MASK,
610                             FIELD_PREP(CECB_GEN_CNTL_CLK_CTRL_MASK,
611                                        CECB_GEN_CNTL_CLK_ENABLE));
612
613         /* Release Reset */
614         regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
615                            CECB_GEN_CNTL_RESET, 0);
616
617         if (ao_cec->data->ctrl2_setup)
618                 regmap_write(ao_cec->regmap_cec, CECB_CTRL2,
619                              FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2));
620
621         meson_ao_cec_g12a_irq_setup(ao_cec, true);
622
623         return 0;
624 }
625
626 static const struct cec_adap_ops meson_ao_cec_g12a_ops = {
627         .adap_enable = meson_ao_cec_g12a_adap_enable,
628         .adap_log_addr = meson_ao_cec_g12a_set_log_addr,
629         .adap_transmit = meson_ao_cec_g12a_transmit,
630 };
631
632 static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
633 {
634         struct meson_ao_cec_g12a_device *ao_cec;
635         struct device *hdmi_dev;
636         struct resource *res;
637         void __iomem *base;
638         int ret, irq;
639
640         hdmi_dev = cec_notifier_parse_hdmi_phandle(&pdev->dev);
641         if (IS_ERR(hdmi_dev))
642                 return PTR_ERR(hdmi_dev);
643
644         ao_cec = devm_kzalloc(&pdev->dev, sizeof(*ao_cec), GFP_KERNEL);
645         if (!ao_cec)
646                 return -ENOMEM;
647
648         ao_cec->data = of_device_get_match_data(&pdev->dev);
649         if (!ao_cec->data) {
650                 dev_err(&pdev->dev, "failed to get match data\n");
651                 return -ENODEV;
652         }
653
654         spin_lock_init(&ao_cec->cec_reg_lock);
655         ao_cec->pdev = pdev;
656
657         ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec,
658                                             "meson_g12a_ao_cec",
659                                             CEC_CAP_DEFAULTS |
660                                             CEC_CAP_CONNECTOR_INFO,
661                                             CEC_MAX_LOG_ADDRS);
662         if (IS_ERR(ao_cec->adap))
663                 return PTR_ERR(ao_cec->adap);
664
665         ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL,
666                                                         ao_cec->adap);
667         if (!ao_cec->notify) {
668                 ret = -ENOMEM;
669                 goto out_probe_adapter;
670         }
671
672         ao_cec->adap->owner = THIS_MODULE;
673
674         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
675         base = devm_ioremap_resource(&pdev->dev, res);
676         if (IS_ERR(base)) {
677                 ret = PTR_ERR(base);
678                 goto out_probe_notify;
679         }
680
681         ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
682                                                &meson_ao_cec_g12a_regmap_conf);
683         if (IS_ERR(ao_cec->regmap)) {
684                 ret = PTR_ERR(ao_cec->regmap);
685                 goto out_probe_notify;
686         }
687
688         ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec,
689                                            &meson_ao_cec_g12a_cec_regmap_conf);
690         if (IS_ERR(ao_cec->regmap_cec)) {
691                 ret = PTR_ERR(ao_cec->regmap_cec);
692                 goto out_probe_notify;
693         }
694
695         irq = platform_get_irq(pdev, 0);
696         ret = devm_request_threaded_irq(&pdev->dev, irq,
697                                         meson_ao_cec_g12a_irq,
698                                         meson_ao_cec_g12a_irq_thread,
699                                         0, NULL, ao_cec);
700         if (ret) {
701                 dev_err(&pdev->dev, "irq request failed\n");
702                 goto out_probe_notify;
703         }
704
705         ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin");
706         if (IS_ERR(ao_cec->oscin)) {
707                 dev_err(&pdev->dev, "oscin clock request failed\n");
708                 ret = PTR_ERR(ao_cec->oscin);
709                 goto out_probe_notify;
710         }
711
712         ret = meson_ao_cec_g12a_setup_clk(ao_cec);
713         if (ret)
714                 goto out_probe_notify;
715
716         ret = clk_prepare_enable(ao_cec->core);
717         if (ret) {
718                 dev_err(&pdev->dev, "core clock enable failed\n");
719                 goto out_probe_notify;
720         }
721
722         device_reset_optional(&pdev->dev);
723
724         platform_set_drvdata(pdev, ao_cec);
725
726         ret = cec_register_adapter(ao_cec->adap, &pdev->dev);
727         if (ret < 0)
728                 goto out_probe_core_clk;
729
730         /* Setup Hardware */
731         regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET);
732
733         return 0;
734
735 out_probe_core_clk:
736         clk_disable_unprepare(ao_cec->core);
737
738 out_probe_notify:
739         cec_notifier_cec_adap_unregister(ao_cec->notify);
740
741 out_probe_adapter:
742         cec_delete_adapter(ao_cec->adap);
743
744         dev_err(&pdev->dev, "CEC controller registration failed\n");
745
746         return ret;
747 }
748
749 static int meson_ao_cec_g12a_remove(struct platform_device *pdev)
750 {
751         struct meson_ao_cec_g12a_device *ao_cec = platform_get_drvdata(pdev);
752
753         clk_disable_unprepare(ao_cec->core);
754
755         cec_notifier_cec_adap_unregister(ao_cec->notify);
756
757         cec_unregister_adapter(ao_cec->adap);
758
759         return 0;
760 }
761
762 static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
763         .ctrl2_setup = false,
764 };
765
766 static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = {
767         .ctrl2_setup = true,
768 };
769
770 static const struct of_device_id meson_ao_cec_g12a_of_match[] = {
771         {
772                 .compatible = "amlogic,meson-g12a-ao-cec",
773                 .data = &ao_cec_g12a_data,
774         },
775         {
776                 .compatible = "amlogic,meson-sm1-ao-cec",
777                 .data = &ao_cec_sm1_data,
778         },
779         { /* sentinel */ }
780 };
781 MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match);
782
783 static struct platform_driver meson_ao_cec_g12a_driver = {
784         .probe   = meson_ao_cec_g12a_probe,
785         .remove  = meson_ao_cec_g12a_remove,
786         .driver  = {
787                 .name = "meson-ao-cec-g12a",
788                 .of_match_table = of_match_ptr(meson_ao_cec_g12a_of_match),
789         },
790 };
791
792 module_platform_driver(meson_ao_cec_g12a_driver);
793
794 MODULE_DESCRIPTION("Meson AO CEC G12A Controller driver");
795 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
796 MODULE_LICENSE("GPL");