1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | // |
3 | // em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices |
4 | // |
5 | // Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> |
6 | // Markus Rechberger <mrechberger@gmail.com> |
7 | // Mauro Carvalho Chehab <mchehab@kernel.org> |
8 | // Sascha Sommer <saschasommer@freenet.de> |
9 | // Copyright (C) 2012 Frank Schäfer <fschaefer.oss@googlemail.com> |
10 | |
11 | #include "em28xx.h" |
12 | |
13 | #include <linux/init.h> |
14 | #include <linux/jiffies.h> |
15 | #include <linux/list.h> |
16 | #include <linux/module.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/usb.h> |
19 | #include <linux/vmalloc.h> |
20 | #include <sound/ac97_codec.h> |
21 | #include <media/v4l2-common.h> |
22 | |
23 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ |
24 | "Markus Rechberger <mrechberger@gmail.com>, " \ |
25 | "Mauro Carvalho Chehab <mchehab@kernel.org>, " \ |
26 | "Sascha Sommer <saschasommer@freenet.de>" |
27 | |
28 | MODULE_AUTHOR(DRIVER_AUTHOR); |
29 | MODULE_DESCRIPTION(DRIVER_DESC); |
30 | MODULE_LICENSE("GPL v2" ); |
31 | MODULE_VERSION(EM28XX_VERSION); |
32 | |
33 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ |
34 | |
35 | static unsigned int core_debug; |
36 | module_param(core_debug, int, 0644); |
37 | MODULE_PARM_DESC(core_debug, "enable debug messages [core and isoc]" ); |
38 | |
39 | #define em28xx_coredbg(fmt, arg...) do { \ |
40 | if (core_debug) \ |
41 | dev_printk(KERN_DEBUG, &dev->intf->dev, \ |
42 | "core: %s: " fmt, __func__, ## arg); \ |
43 | } while (0) |
44 | |
45 | static unsigned int reg_debug; |
46 | module_param(reg_debug, int, 0644); |
47 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]" ); |
48 | |
49 | #define em28xx_regdbg(fmt, arg...) do { \ |
50 | if (reg_debug) \ |
51 | dev_printk(KERN_DEBUG, &dev->intf->dev, \ |
52 | "reg: %s: " fmt, __func__, ## arg); \ |
53 | } while (0) |
54 | |
55 | /* FIXME: don't abuse core_debug */ |
56 | #define em28xx_isocdbg(fmt, arg...) do { \ |
57 | if (core_debug) \ |
58 | dev_printk(KERN_DEBUG, &dev->intf->dev, \ |
59 | "core: %s: " fmt, __func__, ## arg); \ |
60 | } while (0) |
61 | |
62 | /* |
63 | * em28xx_read_reg_req() |
64 | * reads data from the usb device specifying bRequest |
65 | */ |
66 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, |
67 | char *buf, int len) |
68 | { |
69 | int ret; |
70 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
71 | int pipe = usb_rcvctrlpipe(udev, 0); |
72 | |
73 | if (dev->disconnected) |
74 | return -ENODEV; |
75 | |
76 | if (len > URB_MAX_CTRL_SIZE) |
77 | return -EINVAL; |
78 | |
79 | mutex_lock(&dev->ctrl_urb_lock); |
80 | ret = usb_control_msg(dev: udev, pipe, request: req, |
81 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
82 | value: 0x0000, index: reg, data: dev->urb_buf, size: len, timeout: 1000); |
83 | if (ret < 0) { |
84 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n" , |
85 | pipe, |
86 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
87 | req, 0, 0, |
88 | reg & 0xff, reg >> 8, |
89 | len & 0xff, len >> 8, ret); |
90 | mutex_unlock(lock: &dev->ctrl_urb_lock); |
91 | return usb_translate_errors(error_code: ret); |
92 | } |
93 | |
94 | if (len) |
95 | memcpy(buf, dev->urb_buf, len); |
96 | |
97 | mutex_unlock(lock: &dev->ctrl_urb_lock); |
98 | |
99 | em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x <<< %*ph\n" , |
100 | pipe, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
101 | req, 0, 0, |
102 | reg & 0xff, reg >> 8, |
103 | len & 0xff, len >> 8, len, buf); |
104 | |
105 | return ret; |
106 | } |
107 | |
108 | /* |
109 | * em28xx_read_reg_req() |
110 | * reads data from the usb device specifying bRequest |
111 | */ |
112 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) |
113 | { |
114 | int ret; |
115 | u8 val; |
116 | |
117 | ret = em28xx_read_reg_req_len(dev, req, reg, buf: &val, len: 1); |
118 | if (ret < 0) |
119 | return ret; |
120 | |
121 | return val; |
122 | } |
123 | |
124 | int em28xx_read_reg(struct em28xx *dev, u16 reg) |
125 | { |
126 | return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg); |
127 | } |
128 | EXPORT_SYMBOL_GPL(em28xx_read_reg); |
129 | |
130 | /* |
131 | * em28xx_write_regs_req() |
132 | * sends data to the usb device, specifying bRequest |
133 | */ |
134 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, |
135 | int len) |
136 | { |
137 | int ret; |
138 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
139 | int pipe = usb_sndctrlpipe(udev, 0); |
140 | |
141 | if (dev->disconnected) |
142 | return -ENODEV; |
143 | |
144 | if (len < 1 || len > URB_MAX_CTRL_SIZE) |
145 | return -EINVAL; |
146 | |
147 | mutex_lock(&dev->ctrl_urb_lock); |
148 | memcpy(dev->urb_buf, buf, len); |
149 | ret = usb_control_msg(dev: udev, pipe, request: req, |
150 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
151 | value: 0x0000, index: reg, data: dev->urb_buf, size: len, timeout: 1000); |
152 | mutex_unlock(lock: &dev->ctrl_urb_lock); |
153 | |
154 | if (ret < 0) { |
155 | em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph failed with error %i\n" , |
156 | pipe, |
157 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
158 | req, 0, 0, |
159 | reg & 0xff, reg >> 8, |
160 | len & 0xff, len >> 8, len, buf, ret); |
161 | return usb_translate_errors(error_code: ret); |
162 | } |
163 | |
164 | em28xx_regdbg("(pipe 0x%08x): OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>> %*ph\n" , |
165 | pipe, |
166 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
167 | req, 0, 0, |
168 | reg & 0xff, reg >> 8, |
169 | len & 0xff, len >> 8, len, buf); |
170 | |
171 | if (dev->wait_after_write) |
172 | msleep(msecs: dev->wait_after_write); |
173 | |
174 | return ret; |
175 | } |
176 | |
177 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) |
178 | { |
179 | return em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); |
180 | } |
181 | EXPORT_SYMBOL_GPL(em28xx_write_regs); |
182 | |
183 | /* Write a single register */ |
184 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) |
185 | { |
186 | return em28xx_write_regs(dev, reg, &val, 1); |
187 | } |
188 | EXPORT_SYMBOL_GPL(em28xx_write_reg); |
189 | |
190 | /* |
191 | * em28xx_write_reg_bits() |
192 | * sets only some bits (specified by bitmask) of a register, by first reading |
193 | * the actual value |
194 | */ |
195 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, |
196 | u8 bitmask) |
197 | { |
198 | int oldval; |
199 | u8 newval; |
200 | |
201 | oldval = em28xx_read_reg(dev, reg); |
202 | if (oldval < 0) |
203 | return oldval; |
204 | |
205 | newval = (((u8)oldval) & ~bitmask) | (val & bitmask); |
206 | |
207 | return em28xx_write_regs(dev, reg, &newval, 1); |
208 | } |
209 | EXPORT_SYMBOL_GPL(em28xx_write_reg_bits); |
210 | |
211 | /* |
212 | * em28xx_toggle_reg_bits() |
213 | * toggles/inverts the bits (specified by bitmask) of a register |
214 | */ |
215 | int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask) |
216 | { |
217 | int oldval; |
218 | u8 newval; |
219 | |
220 | oldval = em28xx_read_reg(dev, reg); |
221 | if (oldval < 0) |
222 | return oldval; |
223 | |
224 | newval = (~oldval & bitmask) | (oldval & ~bitmask); |
225 | |
226 | return em28xx_write_reg(dev, reg, newval); |
227 | } |
228 | EXPORT_SYMBOL_GPL(em28xx_toggle_reg_bits); |
229 | |
230 | /* |
231 | * em28xx_is_ac97_ready() |
232 | * Checks if ac97 is ready |
233 | */ |
234 | static int em28xx_is_ac97_ready(struct em28xx *dev) |
235 | { |
236 | unsigned long timeout = jiffies + msecs_to_jiffies(EM28XX_AC97_XFER_TIMEOUT); |
237 | int ret; |
238 | |
239 | /* Wait up to 50 ms for AC97 command to complete */ |
240 | while (time_is_after_jiffies(timeout)) { |
241 | ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); |
242 | if (ret < 0) |
243 | return ret; |
244 | |
245 | if (!(ret & 0x01)) |
246 | return 0; |
247 | msleep(msecs: 5); |
248 | } |
249 | |
250 | dev_warn(&dev->intf->dev, |
251 | "AC97 command still being executed: not handled properly!\n" ); |
252 | return -EBUSY; |
253 | } |
254 | |
255 | /* |
256 | * em28xx_read_ac97() |
257 | * write a 16 bit value to the specified AC97 address (LSB first!) |
258 | */ |
259 | int em28xx_read_ac97(struct em28xx *dev, u8 reg) |
260 | { |
261 | int ret; |
262 | u8 addr = (reg & 0x7f) | 0x80; |
263 | __le16 val; |
264 | |
265 | ret = em28xx_is_ac97_ready(dev); |
266 | if (ret < 0) |
267 | return ret; |
268 | |
269 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); |
270 | if (ret < 0) |
271 | return ret; |
272 | |
273 | ret = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R40_AC97LSB, |
274 | (u8 *)&val, sizeof(val)); |
275 | |
276 | if (ret < 0) |
277 | return ret; |
278 | return le16_to_cpu(val); |
279 | } |
280 | EXPORT_SYMBOL_GPL(em28xx_read_ac97); |
281 | |
282 | /* |
283 | * em28xx_write_ac97() |
284 | * write a 16 bit value to the specified AC97 address (LSB first!) |
285 | */ |
286 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) |
287 | { |
288 | int ret; |
289 | u8 addr = reg & 0x7f; |
290 | __le16 value; |
291 | |
292 | value = cpu_to_le16(val); |
293 | |
294 | ret = em28xx_is_ac97_ready(dev); |
295 | if (ret < 0) |
296 | return ret; |
297 | |
298 | ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *)&value, 2); |
299 | if (ret < 0) |
300 | return ret; |
301 | |
302 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); |
303 | if (ret < 0) |
304 | return ret; |
305 | |
306 | return 0; |
307 | } |
308 | EXPORT_SYMBOL_GPL(em28xx_write_ac97); |
309 | |
310 | struct em28xx_vol_itable { |
311 | enum em28xx_amux mux; |
312 | u8 reg; |
313 | }; |
314 | |
315 | static struct em28xx_vol_itable inputs[] = { |
316 | { EM28XX_AMUX_VIDEO, AC97_VIDEO }, |
317 | { EM28XX_AMUX_LINE_IN, AC97_LINE }, |
318 | { EM28XX_AMUX_PHONE, AC97_PHONE }, |
319 | { EM28XX_AMUX_MIC, AC97_MIC }, |
320 | { EM28XX_AMUX_CD, AC97_CD }, |
321 | { EM28XX_AMUX_AUX, AC97_AUX }, |
322 | { EM28XX_AMUX_PCM_OUT, AC97_PCM }, |
323 | }; |
324 | |
325 | static int set_ac97_input(struct em28xx *dev) |
326 | { |
327 | int ret, i; |
328 | enum em28xx_amux amux = dev->ctl_ainput; |
329 | |
330 | /* |
331 | * EM28XX_AMUX_VIDEO2 is a special case used to indicate that |
332 | * em28xx should point to LINE IN, while AC97 should use VIDEO |
333 | */ |
334 | if (amux == EM28XX_AMUX_VIDEO2) |
335 | amux = EM28XX_AMUX_VIDEO; |
336 | |
337 | /* Mute all entres but the one that were selected */ |
338 | for (i = 0; i < ARRAY_SIZE(inputs); i++) { |
339 | if (amux == inputs[i].mux) |
340 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808); |
341 | else |
342 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); |
343 | |
344 | if (ret < 0) |
345 | dev_warn(&dev->intf->dev, |
346 | "couldn't setup AC97 register %d\n" , |
347 | inputs[i].reg); |
348 | } |
349 | return 0; |
350 | } |
351 | |
352 | static int em28xx_set_audio_source(struct em28xx *dev) |
353 | { |
354 | int ret; |
355 | u8 input; |
356 | |
357 | if (dev->board.is_em2800) { |
358 | if (dev->ctl_ainput == EM28XX_AMUX_VIDEO) |
359 | input = EM2800_AUDIO_SRC_TUNER; |
360 | else |
361 | input = EM2800_AUDIO_SRC_LINE; |
362 | |
363 | ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); |
364 | if (ret < 0) |
365 | return ret; |
366 | } |
367 | |
368 | if (dev->has_msp34xx) { |
369 | input = EM28XX_AUDIO_SRC_TUNER; |
370 | } else { |
371 | switch (dev->ctl_ainput) { |
372 | case EM28XX_AMUX_VIDEO: |
373 | input = EM28XX_AUDIO_SRC_TUNER; |
374 | break; |
375 | default: |
376 | input = EM28XX_AUDIO_SRC_LINE; |
377 | break; |
378 | } |
379 | } |
380 | |
381 | if (dev->board.mute_gpio && dev->mute) |
382 | em28xx_gpio_set(dev, gpio: dev->board.mute_gpio); |
383 | else |
384 | em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); |
385 | |
386 | ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); |
387 | if (ret < 0) |
388 | return ret; |
389 | usleep_range(min: 10000, max: 11000); |
390 | |
391 | switch (dev->audio_mode.ac97) { |
392 | case EM28XX_NO_AC97: |
393 | break; |
394 | default: |
395 | ret = set_ac97_input(dev); |
396 | } |
397 | |
398 | return ret; |
399 | } |
400 | |
401 | struct em28xx_vol_otable { |
402 | enum em28xx_aout mux; |
403 | u8 reg; |
404 | }; |
405 | |
406 | static const struct em28xx_vol_otable outputs[] = { |
407 | { EM28XX_AOUT_MASTER, AC97_MASTER }, |
408 | { EM28XX_AOUT_LINE, AC97_HEADPHONE }, |
409 | { EM28XX_AOUT_MONO, AC97_MASTER_MONO }, |
410 | { EM28XX_AOUT_LFE, AC97_CENTER_LFE_MASTER }, |
411 | { EM28XX_AOUT_SURR, AC97_SURROUND_MASTER }, |
412 | }; |
413 | |
414 | int em28xx_audio_analog_set(struct em28xx *dev) |
415 | { |
416 | int ret, i; |
417 | u8 xclk; |
418 | |
419 | if (dev->int_audio_type == EM28XX_INT_AUDIO_NONE) |
420 | return 0; |
421 | |
422 | /* |
423 | * It is assumed that all devices use master volume for output. |
424 | * It would be possible to use also line output. |
425 | */ |
426 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
427 | /* Mute all outputs */ |
428 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { |
429 | ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); |
430 | if (ret < 0) |
431 | dev_warn(&dev->intf->dev, |
432 | "couldn't setup AC97 register %d\n" , |
433 | outputs[i].reg); |
434 | } |
435 | } |
436 | |
437 | xclk = dev->board.xclk & 0x7f; |
438 | if (!dev->mute) |
439 | xclk |= EM28XX_XCLK_AUDIO_UNMUTE; |
440 | |
441 | ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); |
442 | if (ret < 0) |
443 | return ret; |
444 | usleep_range(min: 10000, max: 11000); |
445 | |
446 | /* Selects the proper audio input */ |
447 | ret = em28xx_set_audio_source(dev); |
448 | |
449 | /* Sets volume */ |
450 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
451 | int vol; |
452 | |
453 | em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200); |
454 | em28xx_write_ac97(dev, AC97_EXTENDED_STATUS, 0x0031); |
455 | em28xx_write_ac97(dev, AC97_PCM_LR_ADC_RATE, 0xbb80); |
456 | |
457 | /* LSB: left channel - both channels with the same level */ |
458 | vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); |
459 | |
460 | /* Mute device, if needed */ |
461 | if (dev->mute) |
462 | vol |= 0x8000; |
463 | |
464 | /* Sets volume */ |
465 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { |
466 | if (dev->ctl_aoutput & outputs[i].mux) |
467 | ret = em28xx_write_ac97(dev, outputs[i].reg, |
468 | vol); |
469 | if (ret < 0) |
470 | dev_warn(&dev->intf->dev, |
471 | "couldn't setup AC97 register %d\n" , |
472 | outputs[i].reg); |
473 | } |
474 | |
475 | if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { |
476 | int sel = ac97_return_record_select(a_out: dev->ctl_aoutput); |
477 | |
478 | /* |
479 | * Use the same input for both left and right |
480 | * channels |
481 | */ |
482 | sel |= (sel << 8); |
483 | |
484 | em28xx_write_ac97(dev, AC97_REC_SEL, sel); |
485 | } |
486 | } |
487 | |
488 | return ret; |
489 | } |
490 | EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); |
491 | |
492 | int em28xx_audio_setup(struct em28xx *dev) |
493 | { |
494 | int vid1, vid2, feat, cfg; |
495 | u32 vid = 0; |
496 | u8 i2s_samplerates; |
497 | |
498 | if (dev->chip_id == CHIP_ID_EM2870 || |
499 | dev->chip_id == CHIP_ID_EM2874 || |
500 | dev->chip_id == CHIP_ID_EM28174 || |
501 | dev->chip_id == CHIP_ID_EM28178) { |
502 | /* Digital only device - don't load any alsa module */ |
503 | dev->int_audio_type = EM28XX_INT_AUDIO_NONE; |
504 | dev->usb_audio_type = EM28XX_USB_AUDIO_NONE; |
505 | return 0; |
506 | } |
507 | |
508 | /* See how this device is configured */ |
509 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); |
510 | dev_info(&dev->intf->dev, "Config register raw data: 0x%02x\n" , cfg); |
511 | if (cfg < 0) { /* Register read error */ |
512 | /* Be conservative */ |
513 | dev->int_audio_type = EM28XX_INT_AUDIO_AC97; |
514 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { |
515 | /* The device doesn't have vendor audio at all */ |
516 | dev->int_audio_type = EM28XX_INT_AUDIO_NONE; |
517 | dev->usb_audio_type = EM28XX_USB_AUDIO_NONE; |
518 | return 0; |
519 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { |
520 | dev->int_audio_type = EM28XX_INT_AUDIO_I2S; |
521 | if (dev->chip_id < CHIP_ID_EM2860 && |
522 | (cfg & EM28XX_CHIPCFG_AUDIOMASK) == |
523 | EM2820_CHIPCFG_I2S_1_SAMPRATE) |
524 | i2s_samplerates = 1; |
525 | else if (dev->chip_id >= CHIP_ID_EM2860 && |
526 | (cfg & EM28XX_CHIPCFG_AUDIOMASK) == |
527 | EM2860_CHIPCFG_I2S_5_SAMPRATES) |
528 | i2s_samplerates = 5; |
529 | else |
530 | i2s_samplerates = 3; |
531 | dev_info(&dev->intf->dev, "I2S Audio (%d sample rate(s))\n" , |
532 | i2s_samplerates); |
533 | /* Skip the code that does AC97 vendor detection */ |
534 | dev->audio_mode.ac97 = EM28XX_NO_AC97; |
535 | goto init_audio; |
536 | } else { |
537 | dev->int_audio_type = EM28XX_INT_AUDIO_AC97; |
538 | } |
539 | |
540 | dev->audio_mode.ac97 = EM28XX_AC97_OTHER; |
541 | |
542 | vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); |
543 | if (vid1 < 0) { |
544 | /* |
545 | * Device likely doesn't support AC97 |
546 | * Note: (some) em2800 devices without eeprom reports 0x91 on |
547 | * CHIPCFG register, even not having an AC97 chip |
548 | */ |
549 | dev_warn(&dev->intf->dev, |
550 | "AC97 chip type couldn't be determined\n" ); |
551 | dev->audio_mode.ac97 = EM28XX_NO_AC97; |
552 | if (dev->usb_audio_type == EM28XX_USB_AUDIO_VENDOR) |
553 | dev->usb_audio_type = EM28XX_USB_AUDIO_NONE; |
554 | dev->int_audio_type = EM28XX_INT_AUDIO_NONE; |
555 | goto init_audio; |
556 | } |
557 | |
558 | vid2 = em28xx_read_ac97(dev, AC97_VENDOR_ID2); |
559 | if (vid2 < 0) |
560 | goto init_audio; |
561 | |
562 | vid = vid1 << 16 | vid2; |
563 | dev_warn(&dev->intf->dev, "AC97 vendor ID = 0x%08x\n" , vid); |
564 | |
565 | feat = em28xx_read_ac97(dev, AC97_RESET); |
566 | if (feat < 0) |
567 | goto init_audio; |
568 | |
569 | dev_warn(&dev->intf->dev, "AC97 features = 0x%04x\n" , feat); |
570 | |
571 | /* Try to identify what audio processor we have */ |
572 | if ((vid == 0xffffffff || vid == 0x83847650) && feat == 0x6a90) |
573 | dev->audio_mode.ac97 = EM28XX_AC97_EM202; |
574 | else if ((vid >> 8) == 0x838476) |
575 | dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; |
576 | |
577 | init_audio: |
578 | /* Reports detected AC97 processor */ |
579 | switch (dev->audio_mode.ac97) { |
580 | case EM28XX_NO_AC97: |
581 | dev_info(&dev->intf->dev, "No AC97 audio processor\n" ); |
582 | break; |
583 | case EM28XX_AC97_EM202: |
584 | dev_info(&dev->intf->dev, |
585 | "Empia 202 AC97 audio processor detected\n" ); |
586 | break; |
587 | case EM28XX_AC97_SIGMATEL: |
588 | dev_info(&dev->intf->dev, |
589 | "Sigmatel audio processor detected (stac 97%02x)\n" , |
590 | vid & 0xff); |
591 | break; |
592 | case EM28XX_AC97_OTHER: |
593 | dev_warn(&dev->intf->dev, |
594 | "Unknown AC97 audio processor detected!\n" ); |
595 | break; |
596 | default: |
597 | break; |
598 | } |
599 | |
600 | return em28xx_audio_analog_set(dev); |
601 | } |
602 | EXPORT_SYMBOL_GPL(em28xx_audio_setup); |
603 | |
604 | const struct em28xx_led *em28xx_find_led(struct em28xx *dev, |
605 | enum em28xx_led_role role) |
606 | { |
607 | if (dev->board.leds) { |
608 | u8 k = 0; |
609 | |
610 | while (dev->board.leds[k].role >= 0 && |
611 | dev->board.leds[k].role < EM28XX_NUM_LED_ROLES) { |
612 | if (dev->board.leds[k].role == role) |
613 | return &dev->board.leds[k]; |
614 | k++; |
615 | } |
616 | } |
617 | return NULL; |
618 | } |
619 | EXPORT_SYMBOL_GPL(em28xx_find_led); |
620 | |
621 | int em28xx_capture_start(struct em28xx *dev, int start) |
622 | { |
623 | int rc; |
624 | const struct em28xx_led *led = NULL; |
625 | |
626 | if (dev->chip_id == CHIP_ID_EM2874 || |
627 | dev->chip_id == CHIP_ID_EM2884 || |
628 | dev->chip_id == CHIP_ID_EM28174 || |
629 | dev->chip_id == CHIP_ID_EM28178) { |
630 | /* The Transport Stream Enable Register moved in em2874 */ |
631 | if (dev->dvb_xfer_bulk) { |
632 | /* Max Tx Size = 188 * 256 = 48128 - LCM(188,512) * 2 */ |
633 | em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? |
634 | EM2874_R5D_TS1_PKT_SIZE : |
635 | EM2874_R5E_TS2_PKT_SIZE, |
636 | 0xff); |
637 | } else { |
638 | /* ISOC Maximum Transfer Size = 188 * 5 */ |
639 | em28xx_write_reg(dev, (dev->ts == PRIMARY_TS) ? |
640 | EM2874_R5D_TS1_PKT_SIZE : |
641 | EM2874_R5E_TS2_PKT_SIZE, |
642 | dev->dvb_max_pkt_size_isoc / 188); |
643 | } |
644 | if (dev->ts == PRIMARY_TS) |
645 | rc = em28xx_write_reg_bits(dev, |
646 | EM2874_R5F_TS_ENABLE, |
647 | start ? EM2874_TS1_CAPTURE_ENABLE : 0x00, |
648 | EM2874_TS1_CAPTURE_ENABLE | EM2874_TS1_FILTER_ENABLE | EM2874_TS1_NULL_DISCARD); |
649 | else |
650 | rc = em28xx_write_reg_bits(dev, |
651 | EM2874_R5F_TS_ENABLE, |
652 | start ? EM2874_TS2_CAPTURE_ENABLE : 0x00, |
653 | EM2874_TS2_CAPTURE_ENABLE | EM2874_TS2_FILTER_ENABLE | EM2874_TS2_NULL_DISCARD); |
654 | } else { |
655 | /* FIXME: which is the best order? */ |
656 | /* video registers are sampled by VREF */ |
657 | rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, |
658 | start ? 0x10 : 0x00, 0x10); |
659 | if (rc < 0) |
660 | return rc; |
661 | |
662 | if (start) { |
663 | if (dev->is_webcam) |
664 | rc = em28xx_write_reg(dev, 0x13, 0x0c); |
665 | |
666 | /* Enable video capture */ |
667 | rc = em28xx_write_reg(dev, 0x48, 0x00); |
668 | if (rc < 0) |
669 | return rc; |
670 | |
671 | if (dev->mode == EM28XX_ANALOG_MODE) |
672 | rc = em28xx_write_reg(dev, |
673 | EM28XX_R12_VINENABLE, |
674 | 0x67); |
675 | else |
676 | rc = em28xx_write_reg(dev, |
677 | EM28XX_R12_VINENABLE, |
678 | 0x37); |
679 | if (rc < 0) |
680 | return rc; |
681 | |
682 | usleep_range(min: 10000, max: 11000); |
683 | } else { |
684 | /* disable video capture */ |
685 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); |
686 | } |
687 | } |
688 | |
689 | if (dev->mode == EM28XX_ANALOG_MODE) |
690 | led = em28xx_find_led(dev, EM28XX_LED_ANALOG_CAPTURING); |
691 | else if (dev->ts == PRIMARY_TS) |
692 | led = em28xx_find_led(dev, EM28XX_LED_DIGITAL_CAPTURING); |
693 | else |
694 | led = em28xx_find_led(dev, EM28XX_LED_DIGITAL_CAPTURING_TS2); |
695 | |
696 | if (led) |
697 | em28xx_write_reg_bits(dev, led->gpio_reg, |
698 | (!start ^ led->inverted) ? |
699 | ~led->gpio_mask : led->gpio_mask, |
700 | led->gpio_mask); |
701 | |
702 | return rc; |
703 | } |
704 | |
705 | int em28xx_gpio_set(struct em28xx *dev, const struct em28xx_reg_seq *gpio) |
706 | { |
707 | int rc = 0; |
708 | |
709 | if (!gpio) |
710 | return rc; |
711 | |
712 | if (dev->mode != EM28XX_SUSPEND) { |
713 | em28xx_write_reg(dev, 0x48, 0x00); |
714 | if (dev->mode == EM28XX_ANALOG_MODE) |
715 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); |
716 | else |
717 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); |
718 | usleep_range(min: 10000, max: 11000); |
719 | } |
720 | |
721 | /* Send GPIO reset sequences specified at board entry */ |
722 | while (gpio->sleep >= 0) { |
723 | if (gpio->reg >= 0) { |
724 | rc = em28xx_write_reg_bits(dev, |
725 | gpio->reg, |
726 | gpio->val, |
727 | gpio->mask); |
728 | if (rc < 0) |
729 | return rc; |
730 | } |
731 | if (gpio->sleep > 0) |
732 | msleep(msecs: gpio->sleep); |
733 | |
734 | gpio++; |
735 | } |
736 | return rc; |
737 | } |
738 | EXPORT_SYMBOL_GPL(em28xx_gpio_set); |
739 | |
740 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) |
741 | { |
742 | if (dev->mode == set_mode) |
743 | return 0; |
744 | |
745 | if (set_mode == EM28XX_SUSPEND) { |
746 | dev->mode = set_mode; |
747 | |
748 | /* FIXME: add suspend support for ac97 */ |
749 | |
750 | return em28xx_gpio_set(dev, dev->board.suspend_gpio); |
751 | } |
752 | |
753 | dev->mode = set_mode; |
754 | |
755 | if (dev->mode == EM28XX_DIGITAL_MODE) |
756 | return em28xx_gpio_set(dev, dev->board.dvb_gpio); |
757 | else |
758 | return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); |
759 | } |
760 | EXPORT_SYMBOL_GPL(em28xx_set_mode); |
761 | |
762 | /* |
763 | *URB control |
764 | */ |
765 | |
766 | /* |
767 | * URB completion handler for isoc/bulk transfers |
768 | */ |
769 | static void em28xx_irq_callback(struct urb *urb) |
770 | { |
771 | struct em28xx *dev = urb->context; |
772 | unsigned long flags; |
773 | int i; |
774 | |
775 | switch (urb->status) { |
776 | case 0: /* success */ |
777 | case -ETIMEDOUT: /* NAK */ |
778 | break; |
779 | case -ECONNRESET: /* kill */ |
780 | case -ENOENT: |
781 | case -ESHUTDOWN: |
782 | return; |
783 | default: /* error */ |
784 | em28xx_isocdbg("urb completion error %d.\n" , urb->status); |
785 | break; |
786 | } |
787 | |
788 | /* Copy data from URB */ |
789 | spin_lock_irqsave(&dev->slock, flags); |
790 | dev->usb_ctl.urb_data_copy(dev, urb); |
791 | spin_unlock_irqrestore(lock: &dev->slock, flags); |
792 | |
793 | /* Reset urb buffers */ |
794 | for (i = 0; i < urb->number_of_packets; i++) { |
795 | /* isoc only (bulk: number_of_packets = 0) */ |
796 | urb->iso_frame_desc[i].status = 0; |
797 | urb->iso_frame_desc[i].actual_length = 0; |
798 | } |
799 | urb->status = 0; |
800 | |
801 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); |
802 | if (urb->status) { |
803 | em28xx_isocdbg("urb resubmit failed (error=%i)\n" , |
804 | urb->status); |
805 | } |
806 | } |
807 | |
808 | /* |
809 | * Stop and Deallocate URBs |
810 | */ |
811 | void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) |
812 | { |
813 | struct urb *urb; |
814 | struct em28xx_usb_bufs *usb_bufs; |
815 | int i; |
816 | |
817 | em28xx_isocdbg("called %s in mode %d\n" , __func__, mode); |
818 | |
819 | if (mode == EM28XX_DIGITAL_MODE) |
820 | usb_bufs = &dev->usb_ctl.digital_bufs; |
821 | else |
822 | usb_bufs = &dev->usb_ctl.analog_bufs; |
823 | |
824 | for (i = 0; i < usb_bufs->num_bufs; i++) { |
825 | urb = usb_bufs->urb[i]; |
826 | if (urb) { |
827 | if (!irqs_disabled()) |
828 | usb_kill_urb(urb); |
829 | else |
830 | usb_unlink_urb(urb); |
831 | |
832 | usb_free_urb(urb); |
833 | usb_bufs->urb[i] = NULL; |
834 | } |
835 | } |
836 | |
837 | kfree(objp: usb_bufs->urb); |
838 | kfree(objp: usb_bufs->buf); |
839 | |
840 | usb_bufs->urb = NULL; |
841 | usb_bufs->buf = NULL; |
842 | usb_bufs->num_bufs = 0; |
843 | |
844 | em28xx_capture_start(dev, start: 0); |
845 | } |
846 | EXPORT_SYMBOL_GPL(em28xx_uninit_usb_xfer); |
847 | |
848 | /* |
849 | * Stop URBs |
850 | */ |
851 | void em28xx_stop_urbs(struct em28xx *dev) |
852 | { |
853 | int i; |
854 | struct urb *urb; |
855 | struct em28xx_usb_bufs *isoc_bufs = &dev->usb_ctl.digital_bufs; |
856 | |
857 | em28xx_isocdbg("called %s\n" , __func__); |
858 | |
859 | for (i = 0; i < isoc_bufs->num_bufs; i++) { |
860 | urb = isoc_bufs->urb[i]; |
861 | if (urb) { |
862 | if (!irqs_disabled()) |
863 | usb_kill_urb(urb); |
864 | else |
865 | usb_unlink_urb(urb); |
866 | } |
867 | } |
868 | |
869 | em28xx_capture_start(dev, start: 0); |
870 | } |
871 | EXPORT_SYMBOL_GPL(em28xx_stop_urbs); |
872 | |
873 | /* |
874 | * Allocate URBs |
875 | */ |
876 | int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, |
877 | int num_bufs, int max_pkt_size, int packet_multiplier) |
878 | { |
879 | struct em28xx_usb_bufs *usb_bufs; |
880 | struct urb *urb; |
881 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
882 | int i; |
883 | int sb_size, pipe; |
884 | int j, k; |
885 | |
886 | em28xx_isocdbg("em28xx: called %s in mode %d\n" , __func__, mode); |
887 | |
888 | /* |
889 | * Check mode and if we have an endpoint for the selected |
890 | * transfer type, select buffer |
891 | */ |
892 | if (mode == EM28XX_DIGITAL_MODE) { |
893 | if ((xfer_bulk && !dev->dvb_ep_bulk) || |
894 | (!xfer_bulk && !dev->dvb_ep_isoc)) { |
895 | dev_err(&dev->intf->dev, |
896 | "no endpoint for DVB mode and transfer type %d\n" , |
897 | xfer_bulk > 0); |
898 | return -EINVAL; |
899 | } |
900 | usb_bufs = &dev->usb_ctl.digital_bufs; |
901 | } else if (mode == EM28XX_ANALOG_MODE) { |
902 | if ((xfer_bulk && !dev->analog_ep_bulk) || |
903 | (!xfer_bulk && !dev->analog_ep_isoc)) { |
904 | dev_err(&dev->intf->dev, |
905 | "no endpoint for analog mode and transfer type %d\n" , |
906 | xfer_bulk > 0); |
907 | return -EINVAL; |
908 | } |
909 | usb_bufs = &dev->usb_ctl.analog_bufs; |
910 | } else { |
911 | dev_err(&dev->intf->dev, "invalid mode selected\n" ); |
912 | return -EINVAL; |
913 | } |
914 | |
915 | /* De-allocates all pending stuff */ |
916 | em28xx_uninit_usb_xfer(dev, mode); |
917 | |
918 | usb_bufs->num_bufs = num_bufs; |
919 | |
920 | usb_bufs->urb = kcalloc(n: num_bufs, size: sizeof(void *), GFP_KERNEL); |
921 | if (!usb_bufs->urb) |
922 | return -ENOMEM; |
923 | |
924 | usb_bufs->buf = kcalloc(n: num_bufs, size: sizeof(void *), GFP_KERNEL); |
925 | if (!usb_bufs->buf) { |
926 | kfree(objp: usb_bufs->urb); |
927 | return -ENOMEM; |
928 | } |
929 | |
930 | usb_bufs->max_pkt_size = max_pkt_size; |
931 | if (xfer_bulk) |
932 | usb_bufs->num_packets = 0; |
933 | else |
934 | usb_bufs->num_packets = packet_multiplier; |
935 | dev->usb_ctl.vid_buf = NULL; |
936 | dev->usb_ctl.vbi_buf = NULL; |
937 | |
938 | sb_size = packet_multiplier * usb_bufs->max_pkt_size; |
939 | |
940 | /* allocate urbs and transfer buffers */ |
941 | for (i = 0; i < usb_bufs->num_bufs; i++) { |
942 | urb = usb_alloc_urb(iso_packets: usb_bufs->num_packets, GFP_KERNEL); |
943 | if (!urb) { |
944 | em28xx_uninit_usb_xfer(dev, mode); |
945 | return -ENOMEM; |
946 | } |
947 | usb_bufs->urb[i] = urb; |
948 | |
949 | usb_bufs->buf[i] = kzalloc(size: sb_size, GFP_KERNEL); |
950 | if (!usb_bufs->buf[i]) { |
951 | for (i--; i >= 0; i--) |
952 | kfree(objp: usb_bufs->buf[i]); |
953 | |
954 | em28xx_uninit_usb_xfer(dev, mode); |
955 | return -ENOMEM; |
956 | } |
957 | |
958 | urb->transfer_flags = URB_FREE_BUFFER; |
959 | |
960 | if (xfer_bulk) { /* bulk */ |
961 | pipe = usb_rcvbulkpipe(udev, |
962 | mode == EM28XX_ANALOG_MODE ? |
963 | dev->analog_ep_bulk : |
964 | dev->dvb_ep_bulk); |
965 | usb_fill_bulk_urb(urb, dev: udev, pipe, transfer_buffer: usb_bufs->buf[i], |
966 | buffer_length: sb_size, complete_fn: em28xx_irq_callback, context: dev); |
967 | } else { /* isoc */ |
968 | pipe = usb_rcvisocpipe(udev, |
969 | mode == EM28XX_ANALOG_MODE ? |
970 | dev->analog_ep_isoc : |
971 | dev->dvb_ep_isoc); |
972 | usb_fill_int_urb(urb, dev: udev, pipe, transfer_buffer: usb_bufs->buf[i], |
973 | buffer_length: sb_size, complete_fn: em28xx_irq_callback, context: dev, interval: 1); |
974 | urb->transfer_flags |= URB_ISO_ASAP; |
975 | k = 0; |
976 | for (j = 0; j < usb_bufs->num_packets; j++) { |
977 | urb->iso_frame_desc[j].offset = k; |
978 | urb->iso_frame_desc[j].length = |
979 | usb_bufs->max_pkt_size; |
980 | k += usb_bufs->max_pkt_size; |
981 | } |
982 | } |
983 | |
984 | urb->number_of_packets = usb_bufs->num_packets; |
985 | } |
986 | |
987 | return 0; |
988 | } |
989 | EXPORT_SYMBOL_GPL(em28xx_alloc_urbs); |
990 | |
991 | /* |
992 | * Allocate URBs and start IRQ |
993 | */ |
994 | int em28xx_init_usb_xfer(struct em28xx *dev, enum em28xx_mode mode, |
995 | int xfer_bulk, int num_bufs, int max_pkt_size, |
996 | int packet_multiplier, |
997 | int (*urb_data_copy)(struct em28xx *dev, struct urb *urb)) |
998 | { |
999 | struct em28xx_dmaqueue *dma_q = &dev->vidq; |
1000 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; |
1001 | struct em28xx_usb_bufs *usb_bufs; |
1002 | struct usb_device *udev = interface_to_usbdev(dev->intf); |
1003 | int i; |
1004 | int rc; |
1005 | int alloc; |
1006 | |
1007 | em28xx_isocdbg("em28xx: called %s in mode %d\n" , __func__, mode); |
1008 | |
1009 | dev->usb_ctl.urb_data_copy = urb_data_copy; |
1010 | |
1011 | if (mode == EM28XX_DIGITAL_MODE) { |
1012 | usb_bufs = &dev->usb_ctl.digital_bufs; |
1013 | /* no need to free/alloc usb buffers in digital mode */ |
1014 | alloc = 0; |
1015 | } else { |
1016 | usb_bufs = &dev->usb_ctl.analog_bufs; |
1017 | alloc = 1; |
1018 | } |
1019 | |
1020 | if (alloc) { |
1021 | rc = em28xx_alloc_urbs(dev, mode, xfer_bulk, num_bufs, |
1022 | max_pkt_size, packet_multiplier); |
1023 | if (rc) |
1024 | return rc; |
1025 | } |
1026 | |
1027 | if (xfer_bulk) { |
1028 | rc = usb_clear_halt(dev: udev, pipe: usb_bufs->urb[0]->pipe); |
1029 | if (rc < 0) { |
1030 | dev_err(&dev->intf->dev, |
1031 | "failed to clear USB bulk endpoint stall/halt condition (error=%i)\n" , |
1032 | rc); |
1033 | em28xx_uninit_usb_xfer(dev, mode); |
1034 | return rc; |
1035 | } |
1036 | } |
1037 | |
1038 | init_waitqueue_head(&dma_q->wq); |
1039 | init_waitqueue_head(&vbi_dma_q->wq); |
1040 | |
1041 | em28xx_capture_start(dev, start: 1); |
1042 | |
1043 | /* submit urbs and enables IRQ */ |
1044 | for (i = 0; i < usb_bufs->num_bufs; i++) { |
1045 | rc = usb_submit_urb(urb: usb_bufs->urb[i], GFP_KERNEL); |
1046 | if (rc) { |
1047 | dev_err(&dev->intf->dev, |
1048 | "submit of urb %i failed (error=%i)\n" , i, rc); |
1049 | em28xx_uninit_usb_xfer(dev, mode); |
1050 | return rc; |
1051 | } |
1052 | } |
1053 | |
1054 | return 0; |
1055 | } |
1056 | EXPORT_SYMBOL_GPL(em28xx_init_usb_xfer); |
1057 | |
1058 | /* |
1059 | * Device control list |
1060 | */ |
1061 | |
1062 | static LIST_HEAD(em28xx_devlist); |
1063 | static DEFINE_MUTEX(em28xx_devlist_mutex); |
1064 | |
1065 | /* |
1066 | * Extension interface |
1067 | */ |
1068 | |
1069 | static LIST_HEAD(em28xx_extension_devlist); |
1070 | |
1071 | int em28xx_register_extension(struct em28xx_ops *ops) |
1072 | { |
1073 | struct em28xx *dev = NULL; |
1074 | |
1075 | mutex_lock(&em28xx_devlist_mutex); |
1076 | list_add_tail(new: &ops->next, head: &em28xx_extension_devlist); |
1077 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
1078 | if (ops->init) { |
1079 | ops->init(dev); |
1080 | if (dev->dev_next) |
1081 | ops->init(dev->dev_next); |
1082 | } |
1083 | } |
1084 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1085 | pr_info("em28xx: Registered (%s) extension\n" , ops->name); |
1086 | return 0; |
1087 | } |
1088 | EXPORT_SYMBOL(em28xx_register_extension); |
1089 | |
1090 | void em28xx_unregister_extension(struct em28xx_ops *ops) |
1091 | { |
1092 | struct em28xx *dev = NULL; |
1093 | |
1094 | mutex_lock(&em28xx_devlist_mutex); |
1095 | list_for_each_entry(dev, &em28xx_devlist, devlist) { |
1096 | if (ops->fini) { |
1097 | if (dev->dev_next) |
1098 | ops->fini(dev->dev_next); |
1099 | ops->fini(dev); |
1100 | } |
1101 | } |
1102 | list_del(entry: &ops->next); |
1103 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1104 | pr_info("em28xx: Removed (%s) extension\n" , ops->name); |
1105 | } |
1106 | EXPORT_SYMBOL(em28xx_unregister_extension); |
1107 | |
1108 | void em28xx_init_extension(struct em28xx *dev) |
1109 | { |
1110 | const struct em28xx_ops *ops = NULL; |
1111 | |
1112 | mutex_lock(&em28xx_devlist_mutex); |
1113 | list_add_tail(new: &dev->devlist, head: &em28xx_devlist); |
1114 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1115 | if (ops->init) { |
1116 | ops->init(dev); |
1117 | if (dev->dev_next) |
1118 | ops->init(dev->dev_next); |
1119 | } |
1120 | } |
1121 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1122 | } |
1123 | |
1124 | void em28xx_close_extension(struct em28xx *dev) |
1125 | { |
1126 | const struct em28xx_ops *ops = NULL; |
1127 | |
1128 | mutex_lock(&em28xx_devlist_mutex); |
1129 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1130 | if (ops->fini) { |
1131 | if (dev->dev_next) |
1132 | ops->fini(dev->dev_next); |
1133 | ops->fini(dev); |
1134 | } |
1135 | } |
1136 | list_del(entry: &dev->devlist); |
1137 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1138 | } |
1139 | |
1140 | int em28xx_suspend_extension(struct em28xx *dev) |
1141 | { |
1142 | const struct em28xx_ops *ops = NULL; |
1143 | |
1144 | dev_info(&dev->intf->dev, "Suspending extensions\n" ); |
1145 | mutex_lock(&em28xx_devlist_mutex); |
1146 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1147 | if (!ops->suspend) |
1148 | continue; |
1149 | ops->suspend(dev); |
1150 | if (dev->dev_next) |
1151 | ops->suspend(dev->dev_next); |
1152 | } |
1153 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1154 | return 0; |
1155 | } |
1156 | |
1157 | int em28xx_resume_extension(struct em28xx *dev) |
1158 | { |
1159 | const struct em28xx_ops *ops = NULL; |
1160 | |
1161 | dev_info(&dev->intf->dev, "Resuming extensions\n" ); |
1162 | mutex_lock(&em28xx_devlist_mutex); |
1163 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { |
1164 | if (!ops->resume) |
1165 | continue; |
1166 | ops->resume(dev); |
1167 | if (dev->dev_next) |
1168 | ops->resume(dev->dev_next); |
1169 | } |
1170 | mutex_unlock(lock: &em28xx_devlist_mutex); |
1171 | return 0; |
1172 | } |
1173 | |