Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / bridge / adv7511 / adv7511_cec.c
1 /*
2  * adv7511_cec.c - Analog Devices ADV7511/33 cec driver
3  *
4  * Copyright 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5  *
6  * This program is free software; you may redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17  * SOFTWARE.
18  *
19  */
20
21 #include <linux/device.h>
22 #include <linux/module.h>
23 #include <linux/of_device.h>
24 #include <linux/slab.h>
25 #include <linux/clk.h>
26
27 #include <media/cec.h>
28
29 #include "adv7511.h"
30
31 #define ADV7511_INT1_CEC_MASK \
32         (ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | \
33          ADV7511_INT1_CEC_TX_RETRY_TIMEOUT | ADV7511_INT1_CEC_RX_READY1)
34
35 static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status)
36 {
37         unsigned int offset = adv7511->type == ADV7533 ?
38                                         ADV7533_REG_CEC_OFFSET : 0;
39         unsigned int val;
40
41         if (regmap_read(adv7511->regmap_cec,
42                         ADV7511_REG_CEC_TX_ENABLE + offset, &val))
43                 return;
44
45         if ((val & 0x01) == 0)
46                 return;
47
48         if (tx_raw_status & ADV7511_INT1_CEC_TX_ARBIT_LOST) {
49                 cec_transmit_attempt_done(adv7511->cec_adap,
50                                           CEC_TX_STATUS_ARB_LOST);
51                 return;
52         }
53         if (tx_raw_status & ADV7511_INT1_CEC_TX_RETRY_TIMEOUT) {
54                 u8 status;
55                 u8 err_cnt = 0;
56                 u8 nack_cnt = 0;
57                 u8 low_drive_cnt = 0;
58                 unsigned int cnt;
59
60                 /*
61                  * We set this status bit since this hardware performs
62                  * retransmissions.
63                  */
64                 status = CEC_TX_STATUS_MAX_RETRIES;
65                 if (regmap_read(adv7511->regmap_cec,
66                             ADV7511_REG_CEC_TX_LOW_DRV_CNT + offset, &cnt)) {
67                         err_cnt = 1;
68                         status |= CEC_TX_STATUS_ERROR;
69                 } else {
70                         nack_cnt = cnt & 0xf;
71                         if (nack_cnt)
72                                 status |= CEC_TX_STATUS_NACK;
73                         low_drive_cnt = cnt >> 4;
74                         if (low_drive_cnt)
75                                 status |= CEC_TX_STATUS_LOW_DRIVE;
76                 }
77                 cec_transmit_done(adv7511->cec_adap, status,
78                                   0, nack_cnt, low_drive_cnt, err_cnt);
79                 return;
80         }
81         if (tx_raw_status & ADV7511_INT1_CEC_TX_READY) {
82                 cec_transmit_attempt_done(adv7511->cec_adap, CEC_TX_STATUS_OK);
83                 return;
84         }
85 }
86
87 void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1)
88 {
89         unsigned int offset = adv7511->type == ADV7533 ?
90                                         ADV7533_REG_CEC_OFFSET : 0;
91         const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY |
92                                 ADV7511_INT1_CEC_TX_ARBIT_LOST |
93                                 ADV7511_INT1_CEC_TX_RETRY_TIMEOUT;
94         struct cec_msg msg = {};
95         unsigned int len;
96         unsigned int val;
97         u8 i;
98
99         if (irq1 & irq_tx_mask)
100                 adv_cec_tx_raw_status(adv7511, irq1);
101
102         if (!(irq1 & ADV7511_INT1_CEC_RX_READY1))
103                 return;
104
105         if (regmap_read(adv7511->regmap_cec,
106                         ADV7511_REG_CEC_RX_FRAME_LEN + offset, &len))
107                 return;
108
109         msg.len = len & 0x1f;
110
111         if (msg.len > 16)
112                 msg.len = 16;
113
114         if (!msg.len)
115                 return;
116
117         for (i = 0; i < msg.len; i++) {
118                 regmap_read(adv7511->regmap_cec,
119                             i + ADV7511_REG_CEC_RX_FRAME_HDR + offset, &val);
120                 msg.msg[i] = val;
121         }
122
123         /* toggle to re-enable rx 1 */
124         regmap_write(adv7511->regmap_cec,
125                      ADV7511_REG_CEC_RX_BUFFERS + offset, 1);
126         regmap_write(adv7511->regmap_cec,
127                      ADV7511_REG_CEC_RX_BUFFERS + offset, 0);
128         cec_received_msg(adv7511->cec_adap, &msg);
129 }
130
131 static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable)
132 {
133         struct adv7511 *adv7511 = cec_get_drvdata(adap);
134         unsigned int offset = adv7511->type == ADV7533 ?
135                                         ADV7533_REG_CEC_OFFSET : 0;
136
137         if (adv7511->i2c_cec == NULL)
138                 return -EIO;
139
140         if (!adv7511->cec_enabled_adap && enable) {
141                 /* power up cec section */
142                 regmap_update_bits(adv7511->regmap_cec,
143                                    ADV7511_REG_CEC_CLK_DIV + offset,
144                                    0x03, 0x01);
145                 /* legacy mode and clear all rx buffers */
146                 regmap_write(adv7511->regmap_cec,
147                              ADV7511_REG_CEC_RX_BUFFERS + offset, 0x07);
148                 regmap_write(adv7511->regmap_cec,
149                              ADV7511_REG_CEC_RX_BUFFERS + offset, 0);
150                 /* initially disable tx */
151                 regmap_update_bits(adv7511->regmap_cec,
152                                    ADV7511_REG_CEC_TX_ENABLE + offset, 1, 0);
153                 /* enabled irqs: */
154                 /* tx: ready */
155                 /* tx: arbitration lost */
156                 /* tx: retry timeout */
157                 /* rx: ready 1 */
158                 regmap_update_bits(adv7511->regmap,
159                                    ADV7511_REG_INT_ENABLE(1), 0x3f,
160                                    ADV7511_INT1_CEC_MASK);
161         } else if (adv7511->cec_enabled_adap && !enable) {
162                 regmap_update_bits(adv7511->regmap,
163                                    ADV7511_REG_INT_ENABLE(1), 0x3f, 0);
164                 /* disable address mask 1-3 */
165                 regmap_update_bits(adv7511->regmap_cec,
166                                    ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
167                                    0x70, 0x00);
168                 /* power down cec section */
169                 regmap_update_bits(adv7511->regmap_cec,
170                                    ADV7511_REG_CEC_CLK_DIV + offset,
171                                    0x03, 0x00);
172                 adv7511->cec_valid_addrs = 0;
173         }
174         adv7511->cec_enabled_adap = enable;
175         return 0;
176 }
177
178 static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr)
179 {
180         struct adv7511 *adv7511 = cec_get_drvdata(adap);
181         unsigned int offset = adv7511->type == ADV7533 ?
182                                         ADV7533_REG_CEC_OFFSET : 0;
183         unsigned int i, free_idx = ADV7511_MAX_ADDRS;
184
185         if (!adv7511->cec_enabled_adap)
186                 return addr == CEC_LOG_ADDR_INVALID ? 0 : -EIO;
187
188         if (addr == CEC_LOG_ADDR_INVALID) {
189                 regmap_update_bits(adv7511->regmap_cec,
190                                    ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
191                                    0x70, 0);
192                 adv7511->cec_valid_addrs = 0;
193                 return 0;
194         }
195
196         for (i = 0; i < ADV7511_MAX_ADDRS; i++) {
197                 bool is_valid = adv7511->cec_valid_addrs & (1 << i);
198
199                 if (free_idx == ADV7511_MAX_ADDRS && !is_valid)
200                         free_idx = i;
201                 if (is_valid && adv7511->cec_addr[i] == addr)
202                         return 0;
203         }
204         if (i == ADV7511_MAX_ADDRS) {
205                 i = free_idx;
206                 if (i == ADV7511_MAX_ADDRS)
207                         return -ENXIO;
208         }
209         adv7511->cec_addr[i] = addr;
210         adv7511->cec_valid_addrs |= 1 << i;
211
212         switch (i) {
213         case 0:
214                 /* enable address mask 0 */
215                 regmap_update_bits(adv7511->regmap_cec,
216                                    ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
217                                    0x10, 0x10);
218                 /* set address for mask 0 */
219                 regmap_update_bits(adv7511->regmap_cec,
220                                    ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
221                                    0x0f, addr);
222                 break;
223         case 1:
224                 /* enable address mask 1 */
225                 regmap_update_bits(adv7511->regmap_cec,
226                                    ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
227                                    0x20, 0x20);
228                 /* set address for mask 1 */
229                 regmap_update_bits(adv7511->regmap_cec,
230                                    ADV7511_REG_CEC_LOG_ADDR_0_1 + offset,
231                                    0xf0, addr << 4);
232                 break;
233         case 2:
234                 /* enable address mask 2 */
235                 regmap_update_bits(adv7511->regmap_cec,
236                                    ADV7511_REG_CEC_LOG_ADDR_MASK + offset,
237                                    0x40, 0x40);
238                 /* set address for mask 1 */
239                 regmap_update_bits(adv7511->regmap_cec,
240                                    ADV7511_REG_CEC_LOG_ADDR_2 + offset,
241                                    0x0f, addr);
242                 break;
243         }
244         return 0;
245 }
246
247 static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
248                                      u32 signal_free_time, struct cec_msg *msg)
249 {
250         struct adv7511 *adv7511 = cec_get_drvdata(adap);
251         unsigned int offset = adv7511->type == ADV7533 ?
252                                         ADV7533_REG_CEC_OFFSET : 0;
253         u8 len = msg->len;
254         unsigned int i;
255
256         /*
257          * The number of retries is the number of attempts - 1, but retry
258          * at least once. It's not clear if a value of 0 is allowed, so
259          * let's do at least one retry.
260          */
261         regmap_update_bits(adv7511->regmap_cec,
262                            ADV7511_REG_CEC_TX_RETRY + offset,
263                            0x70, max(1, attempts - 1) << 4);
264
265         /* blocking, clear cec tx irq status */
266         regmap_update_bits(adv7511->regmap, ADV7511_REG_INT(1), 0x38, 0x38);
267
268         /* write data */
269         for (i = 0; i < len; i++)
270                 regmap_write(adv7511->regmap_cec,
271                              i + ADV7511_REG_CEC_TX_FRAME_HDR + offset,
272                              msg->msg[i]);
273
274         /* set length (data + header) */
275         regmap_write(adv7511->regmap_cec,
276                      ADV7511_REG_CEC_TX_FRAME_LEN + offset, len);
277         /* start transmit, enable tx */
278         regmap_write(adv7511->regmap_cec,
279                      ADV7511_REG_CEC_TX_ENABLE + offset, 0x01);
280         return 0;
281 }
282
283 static const struct cec_adap_ops adv7511_cec_adap_ops = {
284         .adap_enable = adv7511_cec_adap_enable,
285         .adap_log_addr = adv7511_cec_adap_log_addr,
286         .adap_transmit = adv7511_cec_adap_transmit,
287 };
288
289 static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511)
290 {
291         adv7511->cec_clk = devm_clk_get(dev, "cec");
292         if (IS_ERR(adv7511->cec_clk)) {
293                 int ret = PTR_ERR(adv7511->cec_clk);
294
295                 adv7511->cec_clk = NULL;
296                 return ret;
297         }
298         clk_prepare_enable(adv7511->cec_clk);
299         adv7511->cec_clk_freq = clk_get_rate(adv7511->cec_clk);
300         return 0;
301 }
302
303 int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511)
304 {
305         unsigned int offset = adv7511->type == ADV7533 ?
306                                                 ADV7533_REG_CEC_OFFSET : 0;
307         int ret = adv7511_cec_parse_dt(dev, adv7511);
308
309         if (ret)
310                 goto err_cec_parse_dt;
311
312         adv7511->cec_adap = cec_allocate_adapter(&adv7511_cec_adap_ops,
313                 adv7511, dev_name(dev), CEC_CAP_DEFAULTS, ADV7511_MAX_ADDRS);
314         if (IS_ERR(adv7511->cec_adap)) {
315                 ret = PTR_ERR(adv7511->cec_adap);
316                 goto err_cec_alloc;
317         }
318
319         regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset, 0);
320         /* cec soft reset */
321         regmap_write(adv7511->regmap_cec,
322                      ADV7511_REG_CEC_SOFT_RESET + offset, 0x01);
323         regmap_write(adv7511->regmap_cec,
324                      ADV7511_REG_CEC_SOFT_RESET + offset, 0x00);
325
326         /* legacy mode */
327         regmap_write(adv7511->regmap_cec,
328                      ADV7511_REG_CEC_RX_BUFFERS + offset, 0x00);
329
330         regmap_write(adv7511->regmap_cec,
331                      ADV7511_REG_CEC_CLK_DIV + offset,
332                      ((adv7511->cec_clk_freq / 750000) - 1) << 2);
333
334         ret = cec_register_adapter(adv7511->cec_adap, dev);
335         if (ret)
336                 goto err_cec_register;
337         return 0;
338
339 err_cec_register:
340         cec_delete_adapter(adv7511->cec_adap);
341         adv7511->cec_adap = NULL;
342 err_cec_alloc:
343         dev_info(dev, "Initializing CEC failed with error %d, disabling CEC\n",
344                  ret);
345 err_cec_parse_dt:
346         regmap_write(adv7511->regmap, ADV7511_REG_CEC_CTRL + offset,
347                      ADV7511_CEC_CTRL_POWER_DOWN);
348         return ret == -EPROBE_DEFER ? ret : 0;
349 }