diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 57af4c17d54f..4ae4fb02164d 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -70,6 +70,7 @@ #define DW2102_VOLTAGE_CTRL (0x1800) #define SU3000_STREAM_CTRL (0x1900) #define DW2102_RC_QUERY (0x1a00) +#define DW2102_LED_CTRL (0x1b00) #define err_str "did not find the firmware file. (%s) " \ "Please see linux/Documentation/dvb/ for more details " \ @@ -509,6 +510,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], obuf, 2, DW210X_WRITE_MSG); break; } + case (DW2102_LED_CTRL): { + u8 obuf[2]; + + obuf[0] = 5; + obuf[1] = msg[j].buf[0]; + ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, + obuf, 2, DW210X_WRITE_MSG); + break; + } /*case 0x55: cx24116 case 0x6a: stv0903 case 0x68: ds3000, stv0903 @@ -844,6 +854,24 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) return 0; } +static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) +{ + static u8 led_off[] = { 0 }; + static u8 led_on[] = { 1 }; + struct i2c_msg msg = { + .addr = DW2102_LED_CTRL, + .flags = 0, + .buf = led_off, + .len = 1 + }; + struct dvb_usb_adapter *udev_adap = + (struct dvb_usb_adapter *)(fe->dvb->priv); + + if (offon) + msg.buf = led_on; + i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); +} + static struct stv0299_config sharp_z0194a_config = { .demod_address = 0x68, .inittab = sharp_z0194a_inittab, @@ -923,6 +951,7 @@ static struct stv0900_config prof_7500_stv0900_config = { .tun1_adc = 0,/* 2 Vpp */ .path1_mode = 3, .tun1_type = 3, + .set_lock_led = dw210x_led_ctrl, }; static struct ds3000_config su3000_ds3000_config = { diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h index e3e35d1ce838..91c7ee8b2313 100644 --- a/drivers/media/dvb/frontends/stv0900.h +++ b/drivers/media/dvb/frontends/stv0900.h @@ -53,6 +53,8 @@ struct stv0900_config { u8 tun2_type; /* Set device param to start dma */ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); + /* Hook for Lock LED */ + void (*set_lock_led)(struct dvb_frontend *fe, int offon); }; #if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 4f5e7d3a0e61..1ca1c835048f 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c @@ -1660,8 +1660,13 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status) | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - } else + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 1); + } else { + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); dprintk("DEMOD LOCK FAIL\n"); + } return 0; } @@ -1831,6 +1836,9 @@ static void stv0900_release(struct dvb_frontend *fe) dprintk("%s\n", __func__); + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); + if ((--(state->internal->dmds_used)) <= 0) { dprintk("%s: Actually removing\n", __func__); @@ -1842,6 +1850,18 @@ static void stv0900_release(struct dvb_frontend *fe) kfree(state); } +static int stv0900_sleep(struct dvb_frontend *fe) +{ + struct stv0900_state *state = fe->demodulator_priv; + + dprintk("%s\n", __func__); + + if (state->config->set_lock_led) + state->config->set_lock_led(fe, 0); + + return 0; +} + static int stv0900_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { @@ -1876,6 +1896,7 @@ static struct dvb_frontend_ops stv0900_ops = { .release = stv0900_release, .init = stv0900_init, .get_frontend = stv0900_get_frontend, + .sleep = stv0900_sleep, .get_frontend_algo = stv0900_frontend_algo, .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, .diseqc_send_master_cmd = stv0900_send_master_cmd,