1 // SPDX-License-Identifier: GPL-2.0-or-later
3 Mantis PCI bridge driver
5 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
10 #include <linux/ioport.h>
11 #include <linux/pci.h>
12 #include <linux/i2c.h>
14 #include <media/dmxdev.h>
15 #include <media/dvbdev.h>
16 #include <media/dvb_demux.h>
17 #include <media/dvb_frontend.h>
18 #include <media/dvb_net.h>
20 #include "mantis_common.h"
21 #include "mantis_reg.h"
22 #include "mantis_i2c.h"
26 static int mantis_i2c_read(struct mantis_pci
*mantis
, const struct i2c_msg
*msg
)
28 u32 rxd
, i
, stat
, trials
;
30 dprintk(MANTIS_INFO
, 0, " %s: Address=[0x%02x] <R>[ ",
33 for (i
= 0; i
< msg
->len
; i
++) {
34 rxd
= (msg
->addr
<< 25) | (1 << 24)
39 if (i
== (msg
->len
- 1))
40 rxd
&= ~MANTIS_I2C_STOP
;
42 mmwrite(MANTIS_INT_I2CDONE
, MANTIS_INT_STAT
);
43 mmwrite(rxd
, MANTIS_I2CDATA_CTL
);
45 /* wait for xfer completion */
46 for (trials
= 0; trials
< TRIALS
; trials
++) {
47 stat
= mmread(MANTIS_INT_STAT
);
48 if (stat
& MANTIS_INT_I2CDONE
)
52 dprintk(MANTIS_TMG
, 0, "I2CDONE: trials=%d\n", trials
);
54 /* wait for xfer completion */
55 for (trials
= 0; trials
< TRIALS
; trials
++) {
56 stat
= mmread(MANTIS_INT_STAT
);
57 if (stat
& MANTIS_INT_I2CRACK
)
61 dprintk(MANTIS_TMG
, 0, "I2CRACK: trials=%d\n", trials
);
63 rxd
= mmread(MANTIS_I2CDATA_CTL
);
64 msg
->buf
[i
] = (u8
)((rxd
>> 8) & 0xFF);
65 dprintk(MANTIS_INFO
, 0, "%02x ", msg
->buf
[i
]);
67 dprintk(MANTIS_INFO
, 0, "]\n");
72 static int mantis_i2c_write(struct mantis_pci
*mantis
, const struct i2c_msg
*msg
)
75 u32 txd
= 0, stat
, trials
;
77 dprintk(MANTIS_INFO
, 0, " %s: Address=[0x%02x] <W>[ ",
80 for (i
= 0; i
< msg
->len
; i
++) {
81 dprintk(MANTIS_INFO
, 0, "%02x ", msg
->buf
[i
]);
82 txd
= (msg
->addr
<< 25) | (msg
->buf
[i
] << 8)
87 if (i
== (msg
->len
- 1))
88 txd
&= ~MANTIS_I2C_STOP
;
90 mmwrite(MANTIS_INT_I2CDONE
, MANTIS_INT_STAT
);
91 mmwrite(txd
, MANTIS_I2CDATA_CTL
);
93 /* wait for xfer completion */
94 for (trials
= 0; trials
< TRIALS
; trials
++) {
95 stat
= mmread(MANTIS_INT_STAT
);
96 if (stat
& MANTIS_INT_I2CDONE
)
100 dprintk(MANTIS_TMG
, 0, "I2CDONE: trials=%d\n", trials
);
102 /* wait for xfer completion */
103 for (trials
= 0; trials
< TRIALS
; trials
++) {
104 stat
= mmread(MANTIS_INT_STAT
);
105 if (stat
& MANTIS_INT_I2CRACK
)
109 dprintk(MANTIS_TMG
, 0, "I2CRACK: trials=%d\n", trials
);
111 dprintk(MANTIS_INFO
, 0, "]\n");
116 static int mantis_i2c_xfer(struct i2c_adapter
*adapter
, struct i2c_msg
*msgs
, int num
)
118 int ret
= 0, i
= 0, trials
;
120 struct mantis_pci
*mantis
;
121 struct mantis_hwconfig
*config
;
123 mantis
= i2c_get_adapdata(adapter
);
125 config
= mantis
->hwconfig
;
128 dprintk(MANTIS_DEBUG
, 1, "Messages:%d", num
);
129 mutex_lock(&mantis
->i2c_lock
);
133 if ((config
->i2c_mode
& MANTIS_BYTE_MODE
) &&
136 (msgs
[i
+ 1].len
< 2) &&
137 (msgs
[i
+ 1].flags
& I2C_M_RD
)) {
139 dprintk(MANTIS_DEBUG
, 0, " Byte MODE:\n");
142 txd
= msgs
[i
].addr
<< 25 | (0x1 << 24)
143 | (msgs
[i
].buf
[0] << 16)
146 mmwrite(txd
, MANTIS_I2CDATA_CTL
);
147 /* wait for xfer completion */
148 for (trials
= 0; trials
< TRIALS
; trials
++) {
149 stat
= mmread(MANTIS_INT_STAT
);
150 if (stat
& MANTIS_INT_I2CDONE
)
154 /* check for xfer completion */
155 if (stat
& MANTIS_INT_I2CDONE
) {
156 /* check xfer was acknowledged */
157 if (stat
& MANTIS_INT_I2CRACK
) {
158 data
= mmread(MANTIS_I2CDATA_CTL
);
159 msgs
[i
+ 1].buf
[0] = (data
>> 8) & 0xff;
160 dprintk(MANTIS_DEBUG
, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data
, msgs
[i
+ 1].buf
[0]);
163 dprintk(MANTIS_ERROR
, 1, " I/O error, LINE:%d", __LINE__
);
169 dprintk(MANTIS_ERROR
, 1, " I/O error, LINE:%d", __LINE__
);
173 i
+= 2; /* Write/Read operation in one go */
177 if (msgs
[i
].flags
& I2C_M_RD
)
178 ret
= mantis_i2c_read(mantis
, &msgs
[i
]);
180 ret
= mantis_i2c_write(mantis
, &msgs
[i
]);
189 mutex_unlock(&mantis
->i2c_lock
);
194 mutex_unlock(&mantis
->i2c_lock
);
198 static u32
mantis_i2c_func(struct i2c_adapter
*adapter
)
200 return I2C_FUNC_SMBUS_EMUL
;
203 static const struct i2c_algorithm mantis_algo
= {
204 .master_xfer
= mantis_i2c_xfer
,
205 .functionality
= mantis_i2c_func
,
208 int mantis_i2c_init(struct mantis_pci
*mantis
)
211 struct i2c_adapter
*i2c_adapter
= &mantis
->adapter
;
212 struct pci_dev
*pdev
= mantis
->pdev
;
214 init_waitqueue_head(&mantis
->i2c_wq
);
215 mutex_init(&mantis
->i2c_lock
);
216 strscpy(i2c_adapter
->name
, "Mantis I2C", sizeof(i2c_adapter
->name
));
217 i2c_set_adapdata(i2c_adapter
, mantis
);
219 i2c_adapter
->owner
= THIS_MODULE
;
220 i2c_adapter
->algo
= &mantis_algo
;
221 i2c_adapter
->algo_data
= NULL
;
222 i2c_adapter
->timeout
= 500;
223 i2c_adapter
->retries
= 3;
224 i2c_adapter
->dev
.parent
= &pdev
->dev
;
226 mantis
->i2c_rc
= i2c_add_adapter(i2c_adapter
);
227 if (mantis
->i2c_rc
< 0)
228 return mantis
->i2c_rc
;
230 dprintk(MANTIS_DEBUG
, 1, "Initializing I2C ..");
232 intstat
= mmread(MANTIS_INT_STAT
);
233 mmread(MANTIS_INT_MASK
);
234 mmwrite(intstat
, MANTIS_INT_STAT
);
235 dprintk(MANTIS_DEBUG
, 1, "Disabling I2C interrupt");
236 mantis_mask_ints(mantis
, MANTIS_INT_I2CDONE
);
240 EXPORT_SYMBOL_GPL(mantis_i2c_init
);
242 int mantis_i2c_exit(struct mantis_pci
*mantis
)
244 dprintk(MANTIS_DEBUG
, 1, "Disabling I2C interrupt");
245 mantis_mask_ints(mantis
, MANTIS_INT_I2CDONE
);
247 dprintk(MANTIS_DEBUG
, 1, "Removing I2C adapter");
248 i2c_del_adapter(&mantis
->adapter
);
252 EXPORT_SYMBOL_GPL(mantis_i2c_exit
);