flexcop-usb.c (8c57a5e7b2820f349c95b8c8393fec1e0f4070d2) flexcop-usb.c (b430eaba0be5eb7140d0065df96982fa6b5ccc1d)
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-usb.c - covers the USB part
4 * see flexcop.c for copyright information
5 */
6#define FC_LOG_PREFIX "flexcop_usb"
7#include "flexcop-usb.h"
8#include "flexcop-common.h"

--- 59 unchanged lines hidden (view full) ---

68 */
69static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read)
70{
71 struct flexcop_usb *fc_usb = fc->bus_specific;
72 u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
73 u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
74 u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
75 (read ? 0x80 : 0);
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-usb.c - covers the USB part
4 * see flexcop.c for copyright information
5 */
6#define FC_LOG_PREFIX "flexcop_usb"
7#include "flexcop-usb.h"
8#include "flexcop-common.h"

--- 59 unchanged lines hidden (view full) ---

68 */
69static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read)
70{
71 struct flexcop_usb *fc_usb = fc->bus_specific;
72 u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
73 u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
74 u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
75 (read ? 0x80 : 0);
76 int ret;
76
77
77 int len = usb_control_msg(fc_usb->udev,
78 mutex_lock(&fc_usb->data_mutex);
79 if (!read)
80 memcpy(fc_usb->data, val, sizeof(*val));
81
82 ret = usb_control_msg(fc_usb->udev,
78 read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
79 request,
80 request_type, /* 0xc0 read or 0x40 write */
81 wAddress,
82 0,
83 read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
84 request,
85 request_type, /* 0xc0 read or 0x40 write */
86 wAddress,
87 0,
83 val,
88 fc_usb->data,
84 sizeof(u32),
85 B2C2_WAIT_FOR_OPERATION_RDW * HZ);
86
89 sizeof(u32),
90 B2C2_WAIT_FOR_OPERATION_RDW * HZ);
91
87 if (len != sizeof(u32)) {
92 if (ret != sizeof(u32)) {
88 err("error while %s dword from %d (%d).", read ? "reading" :
89 "writing", wAddress, wRegOffsPCI);
93 err("error while %s dword from %d (%d).", read ? "reading" :
94 "writing", wAddress, wRegOffsPCI);
90 return -EIO;
95 if (ret >= 0)
96 ret = -EIO;
91 }
97 }
92 return 0;
98
99 if (read && ret >= 0)
100 memcpy(val, fc_usb->data, sizeof(*val));
101 mutex_unlock(&fc_usb->data_mutex);
102
103 return ret;
93}
94/*
95 * DKT 010817 - add support for V8 memory read/write and flash update
96 */
97static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
98 flexcop_usb_request_t req, u8 page, u16 wAddress,
99 u8 *pbBuffer, u32 buflen)
100{
101 u8 request_type = USB_TYPE_VENDOR;
102 u16 wIndex;
104}
105/*
106 * DKT 010817 - add support for V8 memory read/write and flash update
107 */
108static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
109 flexcop_usb_request_t req, u8 page, u16 wAddress,
110 u8 *pbBuffer, u32 buflen)
111{
112 u8 request_type = USB_TYPE_VENDOR;
113 u16 wIndex;
103 int nWaitTime, pipe, len;
114 int nWaitTime, pipe, ret;
104 wIndex = page << 8;
105
115 wIndex = page << 8;
116
117 if (buflen > sizeof(fc_usb->data)) {
118 err("Buffer size bigger than max URB control message\n");
119 return -EIO;
120 }
121
106 switch (req) {
107 case B2C2_USB_READ_V8_MEM:
108 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
109 request_type |= USB_DIR_IN;
110 pipe = B2C2_USB_CTRL_PIPE_IN;
111 break;
112 case B2C2_USB_WRITE_V8_MEM:
113 wIndex |= pbBuffer[0];

--- 8 unchanged lines hidden (view full) ---

122 break;
123 default:
124 deb_info("unsupported request for v8_mem_req %x.\n", req);
125 return -EINVAL;
126 }
127 deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
128 wAddress, wIndex, buflen);
129
122 switch (req) {
123 case B2C2_USB_READ_V8_MEM:
124 nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
125 request_type |= USB_DIR_IN;
126 pipe = B2C2_USB_CTRL_PIPE_IN;
127 break;
128 case B2C2_USB_WRITE_V8_MEM:
129 wIndex |= pbBuffer[0];

--- 8 unchanged lines hidden (view full) ---

138 break;
139 default:
140 deb_info("unsupported request for v8_mem_req %x.\n", req);
141 return -EINVAL;
142 }
143 deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
144 wAddress, wIndex, buflen);
145
130 len = usb_control_msg(fc_usb->udev, pipe,
146 mutex_lock(&fc_usb->data_mutex);
147
148 if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
149 memcpy(fc_usb->data, pbBuffer, buflen);
150
151 ret = usb_control_msg(fc_usb->udev, pipe,
131 req,
132 request_type,
133 wAddress,
134 wIndex,
152 req,
153 request_type,
154 wAddress,
155 wIndex,
135 pbBuffer,
156 fc_usb->data,
136 buflen,
137 nWaitTime * HZ);
157 buflen,
158 nWaitTime * HZ);
159 if (ret != buflen)
160 ret = -EIO;
138
161
139 debug_dump(pbBuffer, len, deb_v8);
140 return len == buflen ? 0 : -EIO;
162 if (ret >= 0) {
163 ret = 0;
164 if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
165 memcpy(pbBuffer, fc_usb->data, buflen);
166 }
167
168 mutex_unlock(&fc_usb->data_mutex);
169
170 debug_dump(pbBuffer, ret, deb_v8);
171 return ret;
141}
142
143#define bytes_left_to_read_on_page(paddr,buflen) \
144 ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
145 ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
146
147static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
148 flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,

--- 42 unchanged lines hidden (view full) ---

191
192static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
193{
194 return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
195 V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
196 fc->dvb_adapter.proposed_mac, 6);
197}
198
172}
173
174#define bytes_left_to_read_on_page(paddr,buflen) \
175 ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
176 ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
177
178static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
179 flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,

--- 42 unchanged lines hidden (view full) ---

222
223static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
224{
225 return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
226 V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
227 fc->dvb_adapter.proposed_mac, 6);
228}
229
199#if 0
200static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
201 flexcop_usb_utility_function_t func, u8 extra, u16 wIndex,
202 u16 buflen, u8 *pvBuffer)
203{
204 u16 wValue;
205 u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
206 int nWaitTime = 2,
207 pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
208 wValue = (func << 8) | extra;
209
210 len = usb_control_msg(fc_usb->udev,pipe,
211 B2C2_USB_UTILITY,
212 request_type,
213 wValue,
214 wIndex,
215 pvBuffer,
216 buflen,
217 nWaitTime * HZ);
218 return len == buflen ? 0 : -EIO;
219}
220#endif
221
222/* usb i2c stuff */
223static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
224 flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
225 u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
226{
227 struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
228 u16 wValue, wIndex;
230/* usb i2c stuff */
231static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
232 flexcop_usb_request_t req, flexcop_usb_i2c_function_t func,
233 u8 chipaddr, u8 addr, u8 *buf, u8 buflen)
234{
235 struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
236 u16 wValue, wIndex;
229 int nWaitTime,pipe,len;
237 int nWaitTime, pipe, ret;
230 u8 request_type = USB_TYPE_VENDOR;
231
238 u8 request_type = USB_TYPE_VENDOR;
239
240 if (buflen > sizeof(fc_usb->data)) {
241 err("Buffer size bigger than max URB control message\n");
242 return -EIO;
243 }
244
232 switch (func) {
233 case USB_FUNC_I2C_WRITE:
234 case USB_FUNC_I2C_MULTIWRITE:
235 case USB_FUNC_I2C_REPEATWRITE:
236 /* DKT 020208 - add this to support special case of DiSEqC */
237 case USB_FUNC_I2C_CHECKWRITE:
238 pipe = B2C2_USB_CTRL_PIPE_OUT;
239 nWaitTime = 2;

--- 12 unchanged lines hidden (view full) ---

252 wValue = (func << 8) | (i2c->port << 4);
253 wIndex = (chipaddr << 8 ) | addr;
254
255 deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
256 func, request_type, req,
257 wValue & 0xff, wValue >> 8,
258 wIndex & 0xff, wIndex >> 8);
259
245 switch (func) {
246 case USB_FUNC_I2C_WRITE:
247 case USB_FUNC_I2C_MULTIWRITE:
248 case USB_FUNC_I2C_REPEATWRITE:
249 /* DKT 020208 - add this to support special case of DiSEqC */
250 case USB_FUNC_I2C_CHECKWRITE:
251 pipe = B2C2_USB_CTRL_PIPE_OUT;
252 nWaitTime = 2;

--- 12 unchanged lines hidden (view full) ---

265 wValue = (func << 8) | (i2c->port << 4);
266 wIndex = (chipaddr << 8 ) | addr;
267
268 deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
269 func, request_type, req,
270 wValue & 0xff, wValue >> 8,
271 wIndex & 0xff, wIndex >> 8);
272
260 len = usb_control_msg(fc_usb->udev,pipe,
273 mutex_lock(&fc_usb->data_mutex);
274
275 if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
276 memcpy(fc_usb->data, buf, buflen);
277
278 ret = usb_control_msg(fc_usb->udev, pipe,
261 req,
262 request_type,
263 wValue,
264 wIndex,
279 req,
280 request_type,
281 wValue,
282 wIndex,
265 buf,
283 fc_usb->data,
266 buflen,
267 nWaitTime * HZ);
284 buflen,
285 nWaitTime * HZ);
268 return len == buflen ? 0 : -EREMOTEIO;
286
287 if (ret != buflen)
288 ret = -EIO;
289
290 if (ret >= 0) {
291 ret = 0;
292 if ((request_type & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
293 memcpy(buf, fc_usb->data, buflen);
294 }
295
296 mutex_unlock(&fc_usb->data_mutex);
297
298 return 0;
269}
270
271/* actual bus specific access functions,
272 make sure prototype are/will be equal to pci */
273static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
274 flexcop_ibi_register reg)
275{
276 flexcop_ibi_value val;

--- 234 unchanged lines hidden (view full) ---

511 if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
512 err("out of memory\n");
513 return -ENOMEM;
514 }
515
516 /* general flexcop init */
517 fc_usb = fc->bus_specific;
518 fc_usb->fc_dev = fc;
299}
300
301/* actual bus specific access functions,
302 make sure prototype are/will be equal to pci */
303static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
304 flexcop_ibi_register reg)
305{
306 flexcop_ibi_value val;

--- 234 unchanged lines hidden (view full) ---

541 if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) {
542 err("out of memory\n");
543 return -ENOMEM;
544 }
545
546 /* general flexcop init */
547 fc_usb = fc->bus_specific;
548 fc_usb->fc_dev = fc;
549 mutex_init(&fc_usb->data_mutex);
519
520 fc->read_ibi_reg = flexcop_usb_read_ibi_reg;
521 fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
522 fc->i2c_request = flexcop_usb_i2c_request;
523 fc->get_mac_addr = flexcop_usb_get_mac_addr;
524
525 fc->stream_control = flexcop_usb_stream_control;
526

--- 61 unchanged lines hidden ---
550
551 fc->read_ibi_reg = flexcop_usb_read_ibi_reg;
552 fc->write_ibi_reg = flexcop_usb_write_ibi_reg;
553 fc->i2c_request = flexcop_usb_i2c_request;
554 fc->get_mac_addr = flexcop_usb_get_mac_addr;
555
556 fc->stream_control = flexcop_usb_stream_control;
557

--- 61 unchanged lines hidden ---