From 786baecfe78f8e25547c628b48a60fc8e5636056 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 14 Jun 2012 16:35:56 -0300 Subject: [media] dvb-usb: move it to drivers/media/usb/dvb-usb As media/dvb will be removed, move it to a proper place. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 389 +++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 drivers/media/usb/dvb-usb-v2/dvb_usb.h (limited to 'drivers/media/usb/dvb-usb-v2/dvb_usb.h') diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h new file mode 100644 index 000000000000..79b3b8b6750d --- /dev/null +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -0,0 +1,389 @@ +/* + * DVB USB framework + * + * Copyright (C) 2004-6 Patrick Boettcher + * Copyright (C) 2012 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef DVB_USB_H +#define DVB_USB_H + +#include +#include +#include + +#include "dvb_frontend.h" +#include "dvb_demux.h" +#include "dvb_net.h" +#include "dmxdev.h" +#include "dvb-usb-ids.h" + +/* + * device file: /dev/dvb/adapter[0-1]/frontend[0-2] + * + * |-- device + * | |-- adapter0 + * | | |-- frontend0 + * | | |-- frontend1 + * | | `-- frontend2 + * | `-- adapter1 + * | |-- frontend0 + * | |-- frontend1 + * | `-- frontend2 + * + * + * Commonly used variable names: + * d = pointer to device (struct dvb_usb_device *) + * adap = pointer to adapter (struct dvb_usb_adapter *) + * fe = pointer to frontend (struct dvb_frontend *) + * + * Use macros defined in that file to resolve needed pointers. + */ + +/* helper macros for every DVB USB driver use */ +#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \ + adapter[adap->id])) +#define adap_to_priv(adap) (adap_to_d(adap)->priv) +#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv)) +#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe))) +#define fe_to_priv(fe) (fe_to_d(fe)->priv) +#define d_to_priv(d) (d->priv) + +#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \ + .type = USB_BULK, \ + .count = count_, \ + .endpoint = endpoint_, \ + .u = { \ + .bulk = { \ + .buffersize = size_, \ + } \ + } \ +} + +#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \ + .type = USB_ISOC, \ + .count = count_, \ + .endpoint = endpoint_, \ + .u = { \ + .isoc = { \ + .framesperurb = frames_, \ + .framesize = size_,\ + .interval = interval_, \ + } \ + } \ +} + +#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \ + .props = (props_), \ + .name = (name_), \ + .rc_map = (rc), \ + }) + +struct dvb_usb_device; +struct dvb_usb_adapter; + +/** + * structure for carrying all needed data from the device driver to the general + * dvb usb routines + * @name: device name + * @rc_map: name of rc codes table + * @props: structure containing all device properties + */ +struct dvb_usb_driver_info { + const char *name; + const char *rc_map; + const struct dvb_usb_device_properties *props; +}; + +/** + * structure for remote controller configuration + * @map_name: name of rc codes table + * @allowed_protos: protocol(s) supported by the driver + * @change_protocol: callback to change protocol + * @query: called to query an event from the device + * @interval: time in ms between two queries + * @driver_type: used to point if a device supports raw mode + * @bulk_mode: device supports bulk mode for rc (disable polling mode) + */ +struct dvb_usb_rc { + const char *map_name; + u64 allowed_protos; + int (*change_protocol)(struct rc_dev *dev, u64 rc_type); + int (*query) (struct dvb_usb_device *d); + unsigned int interval; + const enum rc_driver_type driver_type; + bool bulk_mode; +}; + +/** + * usb streaming configration for adapter + * @type: urb type + * @count: count of used urbs + * @endpoint: stream usb endpoint number + */ +struct usb_data_stream_properties { +#define USB_BULK 1 +#define USB_ISOC 2 + u8 type; + u8 count; + u8 endpoint; + + union { + struct { + unsigned int buffersize; /* per URB */ + } bulk; + struct { + int framesperurb; + int framesize; + int interval; + } isoc; + } u; +}; + +/** + * properties of dvb usb device adapter + * @caps: adapter capabilities + * @pid_filter_count: pid count of adapter pid-filter + * @pid_filter_ctrl: called to enable/disable pid-filter + * @pid_filter: called to set/unset pid for filtering + * @stream: adapter usb stream configuration + */ +#define MAX_NO_OF_FE_PER_ADAP 3 +struct dvb_usb_adapter_properties { +#define DVB_USB_ADAP_HAS_PID_FILTER 0x01 +#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02 +#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04 + u8 caps; + + u8 pid_filter_count; + int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int); + int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int); + + struct usb_data_stream_properties stream; +}; + +/** + * struct dvb_usb_device_properties - properties of a dvb-usb-device + * @driver_name: name of the owning driver module + * @owner: owner of the dvb_adapter + * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro + * @bInterfaceNumber: usb interface number driver binds + * @size_of_priv: bytes allocated for the driver private data + * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent + * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for + * receive + * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message + * @identify_state: called to determine the firmware state (cold or warm) and + * return possible firmware file name to be loaded + * @firmware: name of the firmware file to be loaded + * @download_firmware: called to download the firmware + * @i2c_algo: i2c_algorithm if the device has i2c-adapter + * @num_adapters: dvb usb device adapter count + * @get_adapter_count: called to resolve adapter count + * @adapter: array of all adapter properties of device + * @power_ctrl: called to enable/disable power of the device + * @read_config: called to resolve device configuration + * @read_mac_address: called to resolve adapter mac-address + * @frontend_attach: called to attach the possible frontends + * @tuner_attach: called to attach the possible tuners + * @frontend_ctrl: called to power on/off active frontend + * @streaming_ctrl: called to start/stop the usb streaming of adapter + * @init: called after adapters are created in order to finalize device + * configuration + * @exit: called when driver is unloaded + * @get_rc_config: called to resolve used remote controller configuration + * @get_stream_config: called to resolve input and output stream configuration + * of the adapter just before streaming is started. input stream is transport + * stream from the demodulator and output stream is usb stream to host. + */ +#define MAX_NO_OF_ADAPTER_PER_DEVICE 2 +struct dvb_usb_device_properties { + const char *driver_name; + struct module *owner; + short *adapter_nr; + + u8 bInterfaceNumber; + unsigned int size_of_priv; + u8 generic_bulk_ctrl_endpoint; + u8 generic_bulk_ctrl_endpoint_response; + unsigned int generic_bulk_ctrl_delay; + +#define WARM 0 +#define COLD 1 + int (*identify_state) (struct dvb_usb_device *, const char **); + const char *firmware; +#define RECONNECTS_USB 1 + int (*download_firmware) (struct dvb_usb_device *, + const struct firmware *); + + struct i2c_algorithm *i2c_algo; + + unsigned int num_adapters; + int (*get_adapter_count) (struct dvb_usb_device *); + struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE]; + int (*power_ctrl) (struct dvb_usb_device *, int); + int (*read_config) (struct dvb_usb_device *d); + int (*read_mac_address) (struct dvb_usb_adapter *, u8 []); + int (*frontend_attach) (struct dvb_usb_adapter *); + int (*tuner_attach) (struct dvb_usb_adapter *); + int (*frontend_ctrl) (struct dvb_frontend *, int); + int (*streaming_ctrl) (struct dvb_frontend *, int); + int (*init) (struct dvb_usb_device *); + void (*exit) (struct dvb_usb_device *); + int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *); +#define DVB_USB_FE_TS_TYPE_188 0 +#define DVB_USB_FE_TS_TYPE_204 1 +#define DVB_USB_FE_TS_TYPE_RAW 2 + int (*get_stream_config) (struct dvb_frontend *, u8 *, + struct usb_data_stream_properties *); +}; + +/** + * generic object of an usb stream + * @buf_num: number of buffer allocated + * @buf_size: size of each buffer in buf_list + * @buf_list: array containing all allocate buffers for streaming + * @dma_addr: list of dma_addr_t for each buffer in buf_list + * + * @urbs_initialized: number of URBs initialized + * @urbs_submitted: number of URBs submitted + */ +#define MAX_NO_URBS_FOR_DATA_STREAM 10 +struct usb_data_stream { + struct usb_device *udev; + struct usb_data_stream_properties props; + +#define USB_STATE_INIT 0x00 +#define USB_STATE_URB_BUF 0x01 + u8 state; + + void (*complete) (struct usb_data_stream *, u8 *, size_t); + + struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM]; + int buf_num; + unsigned long buf_size; + u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM]; + dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM]; + + int urbs_initialized; + int urbs_submitted; + + void *user_priv; +}; + +/** + * dvb adapter object on dvb usb device + * @props: pointer to adapter properties + * @stream: adapter the usb data stream + * @id: index of this adapter (starting with 0) + * @ts_type: transport stream, input stream, type + * @pid_filtering: is hardware pid_filtering used or not + * @feed_count: current feed count + * @max_feed_count: maimum feed count device can handle + * @dvb_adap: adapter dvb_adapter + * @dmxdev: adapter dmxdev + * @demux: adapter software demuxer + * @dvb_net: adapter dvb_net interfaces + * @sync_mutex: mutex used to sync control and streaming of the adapter + * @fe: adapter frontends + * @fe_init: rerouted frontend-init function + * @fe_sleep: rerouted frontend-sleep function + */ +struct dvb_usb_adapter { + const struct dvb_usb_adapter_properties *props; + struct usb_data_stream stream; + u8 id; + u8 ts_type; + bool pid_filtering; + u8 feed_count; + u8 max_feed_count; + s8 active_fe; + + /* dvb */ + struct dvb_adapter dvb_adap; + struct dmxdev dmxdev; + struct dvb_demux demux; + struct dvb_net dvb_net; + struct mutex sync_mutex; + + struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP]; + int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *); + int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *); +}; + +/** + * dvb usb device object + * @props: device properties + * @name: device name + * @rc_map: name of rc codes table + * @udev: pointer to the device's struct usb_device + * @intf: pointer to the device's usb interface + * @rc: remote controller configuration + * @probe_work: work to defer .probe() + * @powered: indicated whether the device is power or not + * @usb_mutex: mutex for usb control messages + * @i2c_mutex: mutex for i2c-transfers + * @i2c_adap: device's i2c-adapter + * @rc_dev: rc device for the remote control + * @rc_query_work: work for polling remote + * @priv: private data of the actual driver (allocate by dvb usb, size defined + * in size_of_priv of dvb_usb_properties). + */ +struct dvb_usb_device { + const struct dvb_usb_device_properties *props; + const char *name; + const char *rc_map; + + struct usb_device *udev; + struct usb_interface *intf; + struct dvb_usb_rc rc; + struct work_struct probe_work; + pid_t work_pid; + int powered; + + /* locking */ + struct mutex usb_mutex; + + /* i2c */ + struct mutex i2c_mutex; + struct i2c_adapter i2c_adap; + + struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE]; + + /* remote control */ + struct rc_dev *rc_dev; + char rc_phys[64]; + struct delayed_work rc_query_work; + + void *priv; +}; + +extern int dvb_usbv2_probe(struct usb_interface *, + const struct usb_device_id *); +extern void dvb_usbv2_disconnect(struct usb_interface *); +extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t); +extern int dvb_usbv2_resume(struct usb_interface *); + +/* the generic read/write method for device control */ +extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16); +extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16); + +#endif -- cgit v1.2.3 From 06bae1227aadf51d047f7a75834ed446e56ebae2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Aug 2012 22:21:06 -0300 Subject: [media] dvb_frontend: implement suspend / resume Move initial suspend / resume support from dvb_usb_v2 to dvb_frontend as it is dvb general feature that could be used all dvb devices. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/dvb_frontend.c | 47 ++++++++++++++++---- drivers/media/dvb-core/dvb_frontend.h | 3 +- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 3 ++ drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 66 ++++++++++------------------- 4 files changed, 66 insertions(+), 53 deletions(-) (limited to 'drivers/media/usb/dvb-usb-v2/dvb_usb.h') diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 5fb19eae5a82..aa4d4d85dc20 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -307,15 +307,6 @@ void dvb_frontend_reinitialise(struct dvb_frontend *fe) } EXPORT_SYMBOL(dvb_frontend_reinitialise); -void dvb_frontend_retune(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - fepriv->state = FESTATE_RETUNE; - dvb_frontend_wakeup(fe); -} -EXPORT_SYMBOL(dvb_frontend_retune); - static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) { int q2; @@ -2448,6 +2439,44 @@ static const struct file_operations dvb_frontend_fops = { .llseek = noop_llseek, }; +int dvb_frontend_suspend(struct dvb_frontend *fe) +{ + int ret = 0; + + dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num, + fe->id); + + if (fe->ops.tuner_ops.sleep) + ret = fe->ops.tuner_ops.sleep(fe); + + if (fe->ops.sleep) + ret = fe->ops.sleep(fe); + + return ret; +} +EXPORT_SYMBOL(dvb_frontend_suspend); + +int dvb_frontend_resume(struct dvb_frontend *fe) +{ + struct dvb_frontend_private *fepriv = fe->frontend_priv; + int ret = 0; + + dev_dbg(fe->dvb->device, "%s: adap=%d fe=%d\n", __func__, fe->dvb->num, + fe->id); + + if (fe->ops.init) + ret = fe->ops.init(fe); + + if (fe->ops.tuner_ops.init) + ret = fe->ops.tuner_ops.init(fe); + + fepriv->state = FESTATE_RETUNE; + dvb_frontend_wakeup(fe); + + return ret; +} +EXPORT_SYMBOL(dvb_frontend_resume); + int dvb_register_frontend(struct dvb_adapter* dvb, struct dvb_frontend* fe) { diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 58f6b4c16b40..db309db79bd6 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -418,7 +418,8 @@ extern int dvb_unregister_frontend(struct dvb_frontend *fe); extern void dvb_frontend_detach(struct dvb_frontend *fe); extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); -extern void dvb_frontend_retune(struct dvb_frontend *fe); +extern int dvb_frontend_suspend(struct dvb_frontend *fe); +extern int dvb_frontend_resume(struct dvb_frontend *fe); extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 79b3b8b6750d..63fc275c6497 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -295,6 +295,7 @@ struct usb_data_stream { * @stream: adapter the usb data stream * @id: index of this adapter (starting with 0) * @ts_type: transport stream, input stream, type + * @suspend_resume_active: set when there is ongoing suspend / resume * @pid_filtering: is hardware pid_filtering used or not * @feed_count: current feed count * @max_feed_count: maimum feed count device can handle @@ -312,6 +313,7 @@ struct dvb_usb_adapter { struct usb_data_stream stream; u8 id; u8 ts_type; + bool suspend_resume_active; bool pid_filtering; u8 feed_count; u8 max_feed_count; @@ -381,6 +383,7 @@ extern int dvb_usbv2_probe(struct usb_interface *, extern void dvb_usbv2_disconnect(struct usb_interface *); extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t); extern int dvb_usbv2_resume(struct usb_interface *); +#define dvb_usbv2_reset_resume dvb_usbv2_resume /* the generic read/write method for device control */ extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 7ce8ffef8aca..a0e70e91834a 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -489,6 +489,11 @@ static int dvb_usb_fe_init(struct dvb_frontend *fe) dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); + if (!adap->suspend_resume_active) { + adap->active_fe = fe->id; + mutex_lock(&adap->sync_mutex); + } + ret = dvb_usbv2_device_power_ctrl(d, 1); if (ret < 0) goto err; @@ -504,23 +509,11 @@ static int dvb_usb_fe_init(struct dvb_frontend *fe) if (ret < 0) goto err; } - - return 0; err: - dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); - return ret; -} - -static int dvb_usb_fe_init_lock(struct dvb_frontend *fe) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - mutex_lock(&adap->sync_mutex); - - ret = dvb_usb_fe_init(fe); - adap->active_fe = fe->id; + if (!adap->suspend_resume_active) + mutex_unlock(&adap->sync_mutex); - mutex_unlock(&adap->sync_mutex); + dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); return ret; } @@ -532,6 +525,9 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); + if (!adap->suspend_resume_active) + mutex_lock(&adap->sync_mutex); + if (adap->fe_sleep[fe->id]) { ret = adap->fe_sleep[fe->id](fe); if (ret < 0) @@ -547,23 +543,13 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) ret = dvb_usbv2_device_power_ctrl(d, 0); if (ret < 0) goto err; - - return 0; err: - dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret); - return ret; -} - -static int dvb_usb_fe_sleep_lock(struct dvb_frontend *fe) -{ - int ret; - struct dvb_usb_adapter *adap = fe->dvb->priv; - mutex_lock(&adap->sync_mutex); - - ret = dvb_usb_fe_sleep(fe); - adap->active_fe = -1; + if (!adap->suspend_resume_active) { + adap->active_fe = -1; + mutex_unlock(&adap->sync_mutex); + } - mutex_unlock(&adap->sync_mutex); + dev_dbg(&d->udev->dev, "%s: ret=%d\n", __func__, ret); return ret; } @@ -594,9 +580,9 @@ int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) adap->fe[i]->id = i; /* re-assign sleep and wakeup functions */ adap->fe_init[i] = adap->fe[i]->ops.init; - adap->fe[i]->ops.init = dvb_usb_fe_init_lock; + adap->fe[i]->ops.init = dvb_usb_fe_init; adap->fe_sleep[i] = adap->fe[i]->ops.sleep; - adap->fe[i]->ops.sleep = dvb_usb_fe_sleep_lock; + adap->fe[i]->ops.sleep = dvb_usb_fe_sleep; ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]); if (ret < 0) { @@ -978,6 +964,7 @@ int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg) active_fe = d->adapter[i].active_fe; if (d->adapter[i].dvb_adap.priv && active_fe != -1) { fe = d->adapter[i].fe[active_fe]; + d->adapter[i].suspend_resume_active = true; if (d->props->streaming_ctrl) d->props->streaming_ctrl(fe, 0); @@ -985,10 +972,7 @@ int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg) /* stop usb streaming */ usb_urb_killv2(&d->adapter[i].stream); - if (fe->ops.tuner_ops.sleep) - fe->ops.tuner_ops.sleep(fe); - - dvb_usb_fe_sleep(fe); + dvb_frontend_suspend(fe); } } @@ -1008,19 +992,15 @@ int dvb_usbv2_resume(struct usb_interface *intf) if (d->adapter[i].dvb_adap.priv && active_fe != -1) { fe = d->adapter[i].fe[active_fe]; - dvb_usb_fe_init(fe); - - if (fe->ops.tuner_ops.init) - fe->ops.tuner_ops.init(fe); - - /* acquire dvb-core perform retune */ - dvb_frontend_retune(fe); + dvb_frontend_resume(fe); /* resume usb streaming */ usb_urb_submitv2(&d->adapter[i].stream, NULL); if (d->props->streaming_ctrl) d->props->streaming_ctrl(fe, 1); + + d->adapter[i].suspend_resume_active = false; } } -- cgit v1.2.3 From 15d0883663edccea29eeb9790052a11dd9977157 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Tue, 14 Aug 2012 22:21:07 -0300 Subject: [media] dvb_usb_v2: .reset_resume() support Add .reset_resume() support. Also some other small changes for suspend / resume. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 2 +- drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 42 +++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 9 deletions(-) (limited to 'drivers/media/usb/dvb-usb-v2/dvb_usb.h') diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 63fc275c6497..5a53c6231fc2 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -383,7 +383,7 @@ extern int dvb_usbv2_probe(struct usb_interface *, extern void dvb_usbv2_disconnect(struct usb_interface *); extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t); extern int dvb_usbv2_resume(struct usb_interface *); -#define dvb_usbv2_reset_resume dvb_usbv2_resume +extern int dvb_usbv2_reset_resume(struct usb_interface *); /* the generic read/write method for device control */ extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16); diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index a0e70e91834a..e2d73e1a7ae0 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -952,7 +952,7 @@ EXPORT_SYMBOL(dvb_usbv2_disconnect); int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg) { struct dvb_usb_device *d = usb_get_intfdata(intf); - int i, active_fe; + int ret = 0, i, active_fe; struct dvb_frontend *fe; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -972,18 +972,17 @@ int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg) /* stop usb streaming */ usb_urb_killv2(&d->adapter[i].stream); - dvb_frontend_suspend(fe); + ret = dvb_frontend_suspend(fe); } } - return 0; + return ret; } EXPORT_SYMBOL(dvb_usbv2_suspend); -int dvb_usbv2_resume(struct usb_interface *intf) +static int dvb_usbv2_resume_common(struct dvb_usb_device *d) { - struct dvb_usb_device *d = usb_get_intfdata(intf); - int i, active_fe; + int ret = 0, i, active_fe; struct dvb_frontend *fe; dev_dbg(&d->udev->dev, "%s:\n", __func__); @@ -992,7 +991,7 @@ int dvb_usbv2_resume(struct usb_interface *intf) if (d->adapter[i].dvb_adap.priv && active_fe != -1) { fe = d->adapter[i].fe[active_fe]; - dvb_frontend_resume(fe); + ret = dvb_frontend_resume(fe); /* resume usb streaming */ usb_urb_submitv2(&d->adapter[i].stream, NULL); @@ -1009,10 +1008,37 @@ int dvb_usbv2_resume(struct usb_interface *intf) schedule_delayed_work(&d->rc_query_work, msecs_to_jiffies(d->rc.interval)); - return 0; + return ret; +} + +int dvb_usbv2_resume(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + dev_dbg(&d->udev->dev, "%s:\n", __func__); + + return dvb_usbv2_resume_common(d); } EXPORT_SYMBOL(dvb_usbv2_resume); +int dvb_usbv2_reset_resume(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + int ret; + dev_dbg(&d->udev->dev, "%s:\n", __func__); + + dvb_usbv2_device_power_ctrl(d, 1); + + if (d->props->init) + d->props->init(d); + + ret = dvb_usbv2_resume_common(d); + + dvb_usbv2_device_power_ctrl(d, 0); + + return ret; +} +EXPORT_SYMBOL(dvb_usbv2_reset_resume); + MODULE_VERSION("2.0"); MODULE_AUTHOR("Patrick Boettcher "); MODULE_AUTHOR("Antti Palosaari "); -- cgit v1.2.3 From 4ab79283aa749201aaee9e93a67285719bd2fec2 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 22 Aug 2012 19:41:59 -0300 Subject: [media] dvb_usb_v2: add debug macro dvb_usb_dbg_usb_control_msg For dumping usb_control_msg(). Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/dvb-usb-v2/dvb_usb.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/media/usb/dvb-usb-v2/dvb_usb.h') diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h index 5a53c6231fc2..bae16a1189d6 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h @@ -63,6 +63,17 @@ #define fe_to_priv(fe) (fe_to_d(fe)->priv) #define d_to_priv(d) (d->priv) +#define dvb_usb_dbg_usb_control_msg(udev, r, t, v, i, b, l) { \ + char *direction; \ + if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \ + direction = ">>>"; \ + else \ + direction = "<<<"; \ + dev_dbg(&udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \ + "%s %*ph\n", __func__, t, r, v & 0xff, v >> 8, \ + i & 0xff, i >> 8, l & 0xff, l >> 8, direction, l, b); \ +} + #define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \ .type = USB_BULK, \ .count = count_, \ -- cgit v1.2.3