From 40381cb02fb7fc0b46c55e3a71325b5d930580fa Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Tue, 22 Apr 2008 14:45:42 -0300 Subject: [PATCH] V4L/DVB (7313): pvrusb2: Make LED control into a device-specific attribute The pvrusb2 driver has used hardcoded logic to control the LED on the device. However this is really Hauppauge-specific behavior. This change defines a new device attribute for LED control and sets things up appropriately for Hauppauge devices. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 3 ++ drivers/media/video/pvrusb2/pvrusb2-devattr.h | 8 ++++ drivers/media/video/pvrusb2/pvrusb2-encoder.c | 4 -- .../video/pvrusb2/pvrusb2-hdw-internal.h | 3 ++ drivers/media/video/pvrusb2/pvrusb2-hdw.c | 39 +++++++++++++++---- drivers/media/video/pvrusb2/pvrusb2-hdw.h | 3 -- 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 1a60591e38..638c577e32 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -61,6 +61,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = { .flag_has_composite = !0, .flag_has_svideo = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, + .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, }; @@ -94,6 +95,7 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { .flag_has_composite = !0, .flag_has_svideo = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, + .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, }; @@ -235,6 +237,7 @@ static const struct pvr2_device_desc pvr2_device_75xxx = { .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, + .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, }; diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index 4e4798d613..ce4004978a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -43,6 +43,9 @@ struct pvr2_string_table { #define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1 #define PVR2_DIGITAL_SCHEME_ONAIR 2 +#define PVR2_LED_SCHEME_NONE 0 +#define PVR2_LED_SCHEME_HAUPPAUGE 1 + /* This describes a particular hardware type (except for the USB device ID which must live in a separate structure due to environmental constraints). See the top of pvrusb2-hdw.c for where this is @@ -70,6 +73,11 @@ struct pvr2_device_desc { drivers (search for things which touch this field). */ unsigned int signal_routing_scheme; + /* Indicates scheme for controlling device's LED (if any). The + driver will turn on the LED when streaming is underway. This + contains one of PVR2_LED_SCHEME_XXX. */ + unsigned int led_scheme; + /* Control scheme to use if there is a digital tuner. This contains one of PVR2_DIGITAL_SCHEME_XXX. This is an arbitrary integer scheme id; its meaning is contained entirely within the diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index ccb5d14ddf..324d1bd850 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -480,8 +480,6 @@ int pvr2_encoder_start(struct pvr2_hdw *hdw) /* unmask some interrupts */ pvr2_write_register(hdw, 0x0048, 0xbfffffff); - pvr2_led_ctrl(hdw, 1); - pvr2_encoder_vcmd(hdw,CX2341X_ENC_MUTE_VIDEO,1, hdw->input_val == PVR2_CVAL_INPUT_RADIO ? 1 : 0); @@ -524,8 +522,6 @@ int pvr2_encoder_stop(struct pvr2_hdw *hdw) break; } - pvr2_led_ctrl(hdw, 0); - return status; } diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index af06e6c4b8..bc341ae5c7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -253,6 +253,9 @@ struct pvr2_hdw { PVR2_STATE_xxxx */ unsigned int master_state; + /* True if device led is currently on */ + int led_on; + /* True if states must be re-evaluated */ int state_stale; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 9b1e22f2e5..c51c5cef82 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3357,24 +3357,48 @@ static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl) } -/* Toggle LED */ -int pvr2_led_ctrl(struct pvr2_hdw *hdw, int onoff) +void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) { /* change some GPIO data * * note: bit d7 of dir appears to control the LED, * so we shut it off here. * - * FIXME: is this device-specific? */ - if (onoff) + if (onoff) { pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000481); - else + } else { pvr2_hdw_gpio_chg_dir(hdw, 0xffffffff, 0x00000401); - + } pvr2_hdw_gpio_chg_out(hdw, 0xffffffff, 0x00000000); +} - return 0; + +typedef void (*led_method_func)(struct pvr2_hdw *,int); + +static led_method_func led_methods[] = { + [PVR2_LED_SCHEME_HAUPPAUGE] = pvr2_led_ctrl_hauppauge, +}; + + +/* Toggle LED */ +static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff) +{ + unsigned int scheme_id; + led_method_func fp; + + if ((!onoff) == (!hdw->led_on)) return; + + hdw->led_on = onoff != 0; + + scheme_id = hdw->hdw_desc->led_scheme; + if (scheme_id < ARRAY_SIZE(led_methods)) { + fp = led_methods[scheme_id]; + } else { + fp = NULL; + } + + if (fp) (*fp)(hdw,onoff); } @@ -3871,6 +3895,7 @@ static int pvr2_hdw_state_eval(struct pvr2_hdw *hdw) "Device state change from %s to %s", pvr2_get_state_name(hdw->master_state), pvr2_get_state_name(st)); + pvr2_led_ctrl(hdw,st == PVR2_STATE_RUN); hdw->master_state = st; state_updated = !0; callback_flag = !0; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 4fc9db3eff..57e1ff4914 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -258,9 +258,6 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); /* suspend */ int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *); -/* toggle LED */ -int pvr2_led_ctrl(struct pvr2_hdw *hdw, int onoff); - /* Order decoder to reset */ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); -- 2.39.5