Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/mantis/mantis_core.c
15112 views
1
/*
2
Mantis PCI bridge driver
3
4
Copyright (C) Manu Abraham ([email protected])
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
*/
20
21
#include "mantis_common.h"
22
#include "mantis_core.h"
23
#include "mantis_vp1033.h"
24
#include "mantis_vp1034.h"
25
#include "mantis_vp1041.h"
26
#include "mantis_vp2033.h"
27
#include "mantis_vp2040.h"
28
#include "mantis_vp3030.h"
29
30
static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
31
{
32
int err;
33
struct i2c_msg msg[] = {
34
{
35
.addr = 0x50,
36
.flags = 0,
37
.buf = data,
38
.len = 1
39
}, {
40
.addr = 0x50,
41
.flags = I2C_M_RD,
42
.buf = data,
43
.len = length
44
},
45
};
46
47
err = i2c_transfer(&mantis->adapter, msg, 2);
48
if (err < 0) {
49
dprintk(verbose, MANTIS_ERROR, 1,
50
"ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
51
err, data[0], data[1]);
52
53
return err;
54
}
55
56
return 0;
57
}
58
59
static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
60
{
61
int err;
62
63
struct i2c_msg msg = {
64
.addr = 0x50,
65
.flags = 0,
66
.buf = data,
67
.len = length
68
};
69
70
err = i2c_transfer(&mantis->adapter, &msg, 1);
71
if (err < 0) {
72
dprintk(verbose, MANTIS_ERROR, 1,
73
"ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
74
err, length, data[0], data[1]);
75
76
return err;
77
}
78
79
return 0;
80
}
81
82
static int get_mac_address(struct mantis_pci *mantis)
83
{
84
int err;
85
86
mantis->mac_address[0] = 0x08;
87
err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
88
if (err < 0) {
89
dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
90
91
return err;
92
}
93
dprintk(verbose, MANTIS_ERROR, 0,
94
" MAC Address=[%pM]\n", mantis->mac_address);
95
96
return 0;
97
}
98
99
#define MANTIS_MODEL_UNKNOWN "UNKNOWN"
100
#define MANTIS_DEV_UNKNOWN "UNKNOWN"
101
102
struct mantis_hwconfig unknown_device = {
103
.model_name = MANTIS_MODEL_UNKNOWN,
104
.dev_type = MANTIS_DEV_UNKNOWN,
105
};
106
107
static void mantis_load_config(struct mantis_pci *mantis)
108
{
109
switch (mantis->subsystem_device) {
110
case MANTIS_VP_1033_DVB_S: /* VP-1033 */
111
mantis->hwconfig = &vp1033_mantis_config;
112
break;
113
case MANTIS_VP_1034_DVB_S: /* VP-1034 */
114
mantis->hwconfig = &vp1034_mantis_config;
115
break;
116
case MANTIS_VP_1041_DVB_S2: /* VP-1041 */
117
case TECHNISAT_SKYSTAR_HD2:
118
mantis->hwconfig = &vp1041_mantis_config;
119
break;
120
case MANTIS_VP_2033_DVB_C: /* VP-2033 */
121
mantis->hwconfig = &vp2033_mantis_config;
122
break;
123
case MANTIS_VP_2040_DVB_C: /* VP-2040 */
124
case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */
125
case TECHNISAT_CABLESTAR_HD2:
126
mantis->hwconfig = &vp2040_mantis_config;
127
break;
128
case MANTIS_VP_3030_DVB_T: /* VP-3030 */
129
mantis->hwconfig = &vp3030_mantis_config;
130
break;
131
default:
132
mantis->hwconfig = &unknown_device;
133
break;
134
}
135
}
136
137
int mantis_core_init(struct mantis_pci *mantis)
138
{
139
int err = 0;
140
141
mantis_load_config(mantis);
142
dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
143
mantis->hwconfig->model_name, mantis->hwconfig->dev_type,
144
mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));
145
dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",
146
mantis->revision,
147
mantis->subsystem_vendor, mantis->subsystem_device);
148
dprintk(verbose, MANTIS_ERROR, 0,
149
"irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",
150
mantis->pdev->irq, mantis->latency,
151
mantis->mantis_addr, mantis->mantis_mmio);
152
153
err = mantis_i2c_init(mantis);
154
if (err < 0) {
155
dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
156
return err;
157
}
158
err = get_mac_address(mantis);
159
if (err < 0) {
160
dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
161
return err;
162
}
163
err = mantis_dma_init(mantis);
164
if (err < 0) {
165
dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
166
return err;
167
}
168
err = mantis_dvb_init(mantis);
169
if (err < 0) {
170
dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
171
return err;
172
}
173
err = mantis_uart_init(mantis);
174
if (err < 0) {
175
dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed");
176
return err;
177
}
178
179
return 0;
180
}
181
182
int mantis_core_exit(struct mantis_pci *mantis)
183
{
184
mantis_dma_stop(mantis);
185
dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");
186
187
mantis_uart_exit(mantis);
188
dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");
189
190
if (mantis_dma_exit(mantis) < 0)
191
dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");
192
if (mantis_dvb_exit(mantis) < 0)
193
dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed");
194
if (mantis_i2c_exit(mantis) < 0)
195
dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed");
196
197
return 0;
198
}
199
200
/* Turn the given bit on or off. */
201
void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
202
{
203
u32 cur;
204
205
cur = mmread(MANTIS_GPIF_ADDR);
206
if (value)
207
mantis->gpio_status = cur | (1 << bitpos);
208
else
209
mantis->gpio_status = cur & (~(1 << bitpos));
210
211
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
212
mmwrite(0x00, MANTIS_GPIF_DOUT);
213
udelay(100);
214
}
215
216
/* direction = 0 , no CI passthrough ; 1 , CI passthrough */
217
void mantis_set_direction(struct mantis_pci *mantis, int direction)
218
{
219
u32 reg;
220
221
reg = mmread(0x28);
222
dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup");
223
if (direction == 0x01) {
224
/* to CI */
225
reg |= 0x04;
226
mmwrite(reg, 0x28);
227
reg &= 0xff - 0x04;
228
mmwrite(reg, 0x28);
229
} else {
230
reg &= 0xff - 0x04;
231
mmwrite(reg, 0x28);
232
reg |= 0x04;
233
mmwrite(reg, 0x28);
234
}
235
}
236
237