diff options
Diffstat (limited to 'drivers/media/dvb-frontends')
27 files changed, 480 insertions, 466 deletions
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index 292c9479bb75..310e4b8beae8 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig @@ -264,7 +264,7 @@ config DVB_MB86A16 config DVB_TDA10071 tristate "NXP TDA10071" depends on DVB_CORE && I2C - select REGMAP + select REGMAP_I2C default m if !MEDIA_SUBDRV_AUTOSELECT help Say Y when you want to support this frontend. diff --git a/drivers/media/dvb-frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c index 3559ff230045..f135126bc373 100644 --- a/drivers/media/dvb-frontends/au8522_common.c +++ b/drivers/media/dvb-frontends/au8522_common.c @@ -44,7 +44,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) int ret; u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, + struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, .buf = buf, .len = 3 }; ret = i2c_transfer(state->i2c, &msg, 1); @@ -64,9 +64,9 @@ u8 au8522_readreg(struct au8522_state *state, u16 reg) u8 b1[] = { 0 }; struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, + { .addr = state->config.demod_address, .flags = 0, .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, + { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; ret = i2c_transfer(state->i2c, msg, 2); @@ -140,7 +140,7 @@ EXPORT_SYMBOL(au8522_release_state); static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) { - struct au8522_led_config *led_config = state->config->led_cfg; + struct au8522_led_config *led_config = state->config.led_cfg; u8 val; /* bail out if we can't control an LED */ @@ -170,7 +170,7 @@ static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) */ int au8522_led_ctrl(struct au8522_state *state, int led) { - struct au8522_led_config *led_config = state->config->led_cfg; + struct au8522_led_config *led_config = state->config.led_cfg; int i, ret = 0; /* bail out if we can't control an LED */ diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c index 28d7dc2fee34..c8f13d8370e5 100644 --- a/drivers/media/dvb-frontends/au8522_decoder.c +++ b/drivers/media/dvb-frontends/au8522_decoder.c @@ -730,7 +730,6 @@ static int au8522_probe(struct i2c_client *client, struct v4l2_ctrl_handler *hdl; struct v4l2_subdev *sd; int instance; - struct au8522_config *demod_config; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, @@ -754,15 +753,7 @@ static int au8522_probe(struct i2c_client *client, break; } - demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); - if (demod_config == NULL) { - if (instance == 1) - kfree(state); - return -ENOMEM; - } - demod_config->demod_address = 0x8e >> 1; - - state->config = demod_config; + state->config.demod_address = 0x8e >> 1; state->i2c = client->adapter; sd = &state->sd; @@ -784,8 +775,7 @@ static int au8522_probe(struct i2c_client *client, int err = hdl->error; v4l2_ctrl_handler_free(hdl); - kfree(demod_config); - kfree(state); + au8522_release_state(state); return err; } diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index f956f13fb3dc..6c1e97640f3f 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -566,7 +566,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, VSB_mod_tab[i].reg, VSB_mod_tab[i].data); - au8522_set_if(fe, state->config->vsb_if); + au8522_set_if(fe, state->config.vsb_if); break; case QAM_64: dprintk("%s() QAM 64\n", __func__); @@ -574,7 +574,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, QAM64_mod_tab[i].reg, QAM64_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); + au8522_set_if(fe, state->config.qam_if); break; case QAM_256: if (zv_mode) { @@ -583,7 +583,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, QAM256_mod_tab_zv_mode[i].reg, QAM256_mod_tab_zv_mode[i].data); - au8522_set_if(fe, state->config->qam_if); + au8522_set_if(fe, state->config.qam_if); msleep(100); au8522_writereg(state, 0x821a, 0x00); } else { @@ -592,7 +592,7 @@ static int au8522_enable_modulation(struct dvb_frontend *fe, au8522_writereg(state, QAM256_mod_tab[i].reg, QAM256_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); + au8522_set_if(fe, state->config.qam_if); } break; default: @@ -666,7 +666,7 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) *status |= FE_HAS_LOCK | FE_HAS_SYNC; } - switch (state->config->status_mode) { + switch (state->config.status_mode) { case AU8522_DEMODLOCKING: dprintk("%s() DEMODLOCKING\n", __func__); if (*status & FE_HAS_VITERBI) @@ -704,7 +704,7 @@ static int au8522_read_status(struct dvb_frontend *fe, enum fe_status *status) static int au8522_led_status(struct au8522_state *state, const u16 *snr) { - struct au8522_led_config *led_config = state->config->led_cfg; + struct au8522_led_config *led_config = state->config.led_cfg; int led; u16 strong; @@ -758,7 +758,7 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) au8522_readreg(state, 0x4311), snr); - if (state->config->led_cfg) + if (state->config.led_cfg) au8522_led_status(state, snr); return ret; @@ -866,7 +866,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config, } /* setup the state */ - state->config = config; + state->config = *config; state->i2c = i2c; state->operational_mode = AU8522_DIGITAL_MODE; diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h index 951b3847e6f6..ee330c61aa61 100644 --- a/drivers/media/dvb-frontends/au8522_priv.h +++ b/drivers/media/dvb-frontends/au8522_priv.h @@ -50,7 +50,7 @@ struct au8522_state { struct list_head hybrid_tuner_instance_list; /* configuration settings */ - const struct au8522_config *config; + struct au8522_config config; struct dvb_frontend frontend; diff --git a/drivers/media/dvb-frontends/bsbe1-d01a.h b/drivers/media/dvb-frontends/bsbe1-d01a.h index 7ed3c424178c..baaf89e768cf 100644 --- a/drivers/media/dvb-frontends/bsbe1-d01a.h +++ b/drivers/media/dvb-frontends/bsbe1-d01a.h @@ -21,7 +21,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef BSBE1_D01A_H diff --git a/drivers/media/dvb-frontends/bsbe1.h b/drivers/media/dvb-frontends/bsbe1.h index 53e4d0dbb745..4ad766154741 100644 --- a/drivers/media/dvb-frontends/bsbe1.h +++ b/drivers/media/dvb-frontends/bsbe1.h @@ -19,7 +19,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef BSBE1_H diff --git a/drivers/media/dvb-frontends/bsru6.h b/drivers/media/dvb-frontends/bsru6.h index c2a578e1314d..275c1782597d 100644 --- a/drivers/media/dvb-frontends/bsru6.h +++ b/drivers/media/dvb-frontends/bsru6.h @@ -19,7 +19,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef BSRU6_H diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c index b46450a10b80..6913cd687b4d 100644 --- a/drivers/media/dvb-frontends/isl6405.c +++ b/drivers/media/dvb-frontends/isl6405.c @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #include <linux/delay.h> #include <linux/errno.h> diff --git a/drivers/media/dvb-frontends/isl6405.h b/drivers/media/dvb-frontends/isl6405.h index 3c148b830bd1..4a23d3bdf3e6 100644 --- a/drivers/media/dvb-frontends/isl6405.h +++ b/drivers/media/dvb-frontends/isl6405.h @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef _ISL6405_H diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c index 3a4d4606a426..0b6d3837d5de 100644 --- a/drivers/media/dvb-frontends/isl6421.c +++ b/drivers/media/dvb-frontends/isl6421.c @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #include <linux/delay.h> #include <linux/errno.h> diff --git a/drivers/media/dvb-frontends/isl6421.h b/drivers/media/dvb-frontends/isl6421.h index 3273597833fd..00f9874ca5a2 100644 --- a/drivers/media/dvb-frontends/isl6421.h +++ b/drivers/media/dvb-frontends/isl6421.h @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef _ISL6421_H diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c index 4aca0fb9a8a7..6261460d93a7 100644 --- a/drivers/media/dvb-frontends/lnbp21.c +++ b/drivers/media/dvb-frontends/lnbp21.c @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #include <linux/delay.h> #include <linux/errno.h> diff --git a/drivers/media/dvb-frontends/lnbp21.h b/drivers/media/dvb-frontends/lnbp21.h index a9b530de62a6..cd9101f6e579 100644 --- a/drivers/media/dvb-frontends/lnbp21.h +++ b/drivers/media/dvb-frontends/lnbp21.h @@ -21,7 +21,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef _LNBP21_H diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c index d7ca0fdd0084..5c5fd04fd4a7 100644 --- a/drivers/media/dvb-frontends/lnbp22.c +++ b/drivers/media/dvb-frontends/lnbp22.c @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #include <linux/delay.h> #include <linux/errno.h> diff --git a/drivers/media/dvb-frontends/lnbp22.h b/drivers/media/dvb-frontends/lnbp22.h index 628148385182..5d01d92814c2 100644 --- a/drivers/media/dvb-frontends/lnbp22.h +++ b/drivers/media/dvb-frontends/lnbp22.h @@ -22,7 +22,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * the project's page is at http://www.linuxtv.org + * the project's page is at https://linuxtv.org */ #ifndef _LNBP22_H diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 78b87b260d74..10f2119935da 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -976,7 +976,8 @@ static int rtl2832_regmap_read(void *context, const void *reg_buf, ret = __i2c_transfer(client->adapter, msg, 2); if (ret != 2) { - dev_warn(&client->dev, "i2c reg read failed %d\n", ret); + dev_warn(&client->dev, "i2c reg read failed %d reg %02x\n", + ret, *(u8 *)reg_buf); if (ret >= 0) ret = -EREMOTEIO; return ret; @@ -999,7 +1000,8 @@ static int rtl2832_regmap_write(void *context, const void *data, size_t count) ret = __i2c_transfer(client->adapter, msg, 1); if (ret != 1) { - dev_warn(&client->dev, "i2c reg write failed %d\n", ret); + dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n", + ret, *(u8 *)data); if (ret >= 0) ret = -EREMOTEIO; return ret; @@ -1028,7 +1030,8 @@ static int rtl2832_regmap_gather_write(void *context, const void *reg, ret = __i2c_transfer(client->adapter, msg, 1); if (ret != 1) { - dev_warn(&client->dev, "i2c reg write failed %d\n", ret); + dev_warn(&client->dev, "i2c reg write failed %d reg %02x\n", + ret, *(u8 const *)reg); if (ret >= 0) ret = -EREMOTEIO; return ret; @@ -1097,18 +1100,6 @@ static int rtl2832_enable_slave_ts(struct i2c_client *client) if (ret) goto err; - ret = rtl2832_bulk_write(client, 0x022, "\x01", 1); - if (ret) - goto err; - - ret = rtl2832_bulk_write(client, 0x026, "\x1f", 1); - if (ret) - goto err; - - ret = rtl2832_bulk_write(client, 0x027, "\xff", 1); - if (ret) - goto err; - ret = rtl2832_bulk_write(client, 0x192, "\x7f\xf7\xff", 3); if (ret) goto err; diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index dcd8d94c1037..b860f02a4e55 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -310,7 +310,7 @@ static void rtl2832_sdr_urb_complete(struct urb *urb) len = rtl2832_sdr_convert_stream(dev, ptr, urb->transfer_buffer, urb->actual_length); vb2_set_plane_payload(&fbuf->vb.vb2_buf, 0, len); - v4l2_get_timestamp(&fbuf->vb.timestamp); + fbuf->vb.vb2_buf.timestamp = ktime_get_ns(); fbuf->vb.sequence = dev->sequence++; vb2_buffer_done(&fbuf->vb.vb2_buf, VB2_BUF_STATE_DONE); } @@ -490,7 +490,7 @@ static int rtl2832_sdr_querycap(struct file *file, void *fh, /* Videobuf2 operations */ static int rtl2832_sdr_queue_setup(struct vb2_queue *vq, - const void *parg, unsigned int *nbuffers, + unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { struct rtl2832_sdr_dev *dev = vb2_get_drv_priv(vq); diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 7c2eeee69757..1cf6e52e0105 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -1,21 +1,21 @@ /* - Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator - - Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org> - - 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. - - References: - http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf -*/ + * Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator + * + * Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org> + * + * 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. + * + * References: + * http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf + */ #include <linux/delay.h> #include <linux/errno.h> @@ -31,16 +31,18 @@ #include "si2165_priv.h" #include "si2165.h" -/* Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx - * uses 16 MHz xtal */ - -/* Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx - * uses 24 MHz clock provided by tuner */ +/* + * Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx + * uses 16 MHz xtal + * + * Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx + * uses 24 MHz clock provided by tuner + */ struct si2165_state { struct i2c_adapter *i2c; - struct dvb_frontend frontend; + struct dvb_frontend fe; struct si2165_config config; @@ -241,6 +243,27 @@ err: return ret; } +#define REG16(reg, val) { (reg), (val) & 0xff }, { (reg)+1, (val)>>8 & 0xff } +struct si2165_reg_value_pair { + u16 reg; + u8 val; +}; + +static int si2165_write_reg_list(struct si2165_state *state, + const struct si2165_reg_value_pair *regs, + int count) +{ + int i; + int ret; + + for (i = 0; i < count; i++) { + ret = si2165_writereg8(state, regs[i].reg, regs[i].val); + if (ret < 0) + return ret; + } + return 0; +} + static int si2165_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) { @@ -258,8 +281,10 @@ static int si2165_init_pll(struct si2165_state *state) u8 divl = 12; u8 buf[4]; - /* hardcoded values can be deleted if calculation is verified - * or it yields the same values as the windows driver */ + /* + * hardcoded values can be deleted if calculation is verified + * or it yields the same values as the windows driver + */ switch (ref_freq_Hz) { case 16000000u: divn = 56; @@ -274,8 +299,10 @@ static int si2165_init_pll(struct si2165_state *state) if (ref_freq_Hz > 16000000u) divr = 2; - /* now select divn and divp such that - * fvco is in 1624..1824 MHz */ + /* + * now select divn and divp such that + * fvco is in 1624..1824 MHz + */ if (1624000000u * divr > ref_freq_Hz * 2u * 63u) divp = 4; @@ -341,10 +368,12 @@ static int si2165_upload_firmware_block(struct si2165_state *state, if (len % 4 != 0) return -EINVAL; - deb_fw_load("si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n", + deb_fw_load( + "si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n", len, offset, block_count); while (offset+12 <= len && cur_block < block_count) { - deb_fw_load("si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n", + deb_fw_load( + "si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n", len, offset, cur_block, block_count); wordcount = data[offset]; if (wordcount < 1 || data[offset+1] || @@ -383,7 +412,8 @@ static int si2165_upload_firmware_block(struct si2165_state *state, cur_block++; } - deb_fw_load("si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n", + deb_fw_load( + "si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n", len, offset, cur_block, block_count); if (poffset) @@ -633,7 +663,7 @@ static int si2165_init(struct dvb_frontend *fe) goto error; /* ber_pkt */ - ret = si2165_writereg16(state, 0x0470 , 0x7530); + ret = si2165_writereg16(state, 0x0470, 0x7530); if (ret < 0) goto error; @@ -660,22 +690,19 @@ static int si2165_init(struct dvb_frontend *fe) goto error; } - /* write adc values after each reset*/ - ret = si2165_writereg8(state, 0x012a, 0x46); - if (ret < 0) - goto error; - ret = si2165_writereg8(state, 0x012c, 0x00); + /* ts output config */ + ret = si2165_writereg8(state, 0x04e4, 0x20); if (ret < 0) - goto error; - ret = si2165_writereg8(state, 0x012e, 0x0a); + return ret; + ret = si2165_writereg16(state, 0x04ef, 0x00fe); if (ret < 0) - goto error; - ret = si2165_writereg8(state, 0x012f, 0xff); + return ret; + ret = si2165_writereg24(state, 0x04f4, 0x555555); if (ret < 0) - goto error; - ret = si2165_writereg8(state, 0x0123, 0x70); + return ret; + ret = si2165_writereg8(state, 0x04e5, 0x01); if (ret < 0) - goto error; + return ret; return 0; error: @@ -733,16 +760,26 @@ static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate) do_div(oversamp, dvb_rate); reg_value = oversamp & 0x3fffffff; - /* oversamp, usbdump contained 0x03100000; */ + dprintk("%s: Write oversamp=%#x\n", __func__, reg_value); return si2165_writereg32(state, 0x00e4, reg_value); } -static int si2165_set_if_freq_shift(struct si2165_state *state, u32 IF) +static int si2165_set_if_freq_shift(struct si2165_state *state) { + struct dvb_frontend *fe = &state->fe; u64 if_freq_shift; s32 reg_value = 0; u32 fe_clk = si2165_get_fe_clk(state); + u32 IF = 0; + if (!fe->ops.tuner_ops.get_if_frequency) { + dev_err(&state->i2c->dev, + "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n", + KBUILD_MODNAME); + return -EINVAL; + } + + fe->ops.tuner_ops.get_if_frequency(fe, &IF); if_freq_shift = IF; if_freq_shift <<= 29; @@ -758,25 +795,39 @@ static int si2165_set_if_freq_shift(struct si2165_state *state, u32 IF) return si2165_writereg32(state, 0x00e8, reg_value); } -static int si2165_set_parameters(struct dvb_frontend *fe) +static const struct si2165_reg_value_pair dvbt_regs[] = { + /* standard = DVB-T */ + { 0x00ec, 0x01 }, + { 0x08f8, 0x00 }, + /* impulsive_noise_remover */ + { 0x031c, 0x01 }, + { 0x00cb, 0x00 }, + /* agc2 */ + { 0x016e, 0x41 }, + { 0x016c, 0x0e }, + { 0x016d, 0x10 }, + /* agc */ + { 0x015b, 0x03 }, + { 0x0150, 0x78 }, + /* agc */ + { 0x01a0, 0x78 }, + { 0x01c8, 0x68 }, + /* freq_sync_range */ + REG16(0x030c, 0x0064), + /* gp_reg0 */ + { 0x0387, 0x00 } +}; + +static int si2165_set_frontend_dvbt(struct dvb_frontend *fe) { int ret; struct dtv_frontend_properties *p = &fe->dtv_property_cache; struct si2165_state *state = fe->demodulator_priv; - u8 val[3]; - u32 IF; u32 dvb_rate = 0; u16 bw10k; dprintk("%s: called\n", __func__); - if (!fe->ops.tuner_ops.get_if_frequency) { - dev_err(&state->i2c->dev, - "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n", - KBUILD_MODNAME); - return -EINVAL; - } - if (!state->has_dvbt) return -EINVAL; @@ -788,34 +839,10 @@ static int si2165_set_parameters(struct dvb_frontend *fe) bw10k = 800; } - /* standard = DVB-T */ - ret = si2165_writereg8(state, 0x00ec, 0x01); - if (ret < 0) - return ret; ret = si2165_adjust_pll_divl(state, 12); if (ret < 0) return ret; - fe->ops.tuner_ops.get_if_frequency(fe, &IF); - ret = si2165_set_if_freq_shift(state, IF); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x08f8, 0x00); - if (ret < 0) - return ret; - /* ts output config */ - ret = si2165_writereg8(state, 0x04e4, 0x20); - if (ret < 0) - return ret; - ret = si2165_writereg16(state, 0x04ef, 0x00fe); - if (ret < 0) - return ret; - ret = si2165_writereg24(state, 0x04f4, 0x555555); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x04e5, 0x01); - if (ret < 0) - return ret; /* bandwidth in 10KHz steps */ ret = si2165_writereg16(state, 0x0308, bw10k); if (ret < 0) @@ -823,48 +850,115 @@ static int si2165_set_parameters(struct dvb_frontend *fe) ret = si2165_set_oversamp(state, dvb_rate); if (ret < 0) return ret; - /* impulsive_noise_remover */ - ret = si2165_writereg8(state, 0x031c, 0x01); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x00cb, 0x00); + + ret = si2165_write_reg_list(state, dvbt_regs, ARRAY_SIZE(dvbt_regs)); if (ret < 0) return ret; + + return 0; +} + +static const struct si2165_reg_value_pair dvbc_regs[] = { + /* standard = DVB-C */ + { 0x00ec, 0x05 }, + { 0x08f8, 0x00 }, + /* agc2 */ - ret = si2165_writereg8(state, 0x016e, 0x41); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x016c, 0x0e); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x016d, 0x10); - if (ret < 0) - return ret; + { 0x016e, 0x50 }, + { 0x016c, 0x0e }, + { 0x016d, 0x10 }, /* agc */ - ret = si2165_writereg8(state, 0x015b, 0x03); - if (ret < 0) - return ret; - ret = si2165_writereg8(state, 0x0150, 0x78); - if (ret < 0) - return ret; + { 0x015b, 0x03 }, + { 0x0150, 0x68 }, /* agc */ - ret = si2165_writereg8(state, 0x01a0, 0x78); + { 0x01a0, 0x68 }, + { 0x01c8, 0x50 }, + + { 0x0278, 0x0d }, + + { 0x023a, 0x05 }, + { 0x0261, 0x09 }, + REG16(0x0350, 0x3e80), + { 0x02f4, 0x00 }, + + { 0x00cb, 0x01 }, + REG16(0x024c, 0x0000), + REG16(0x027c, 0x0000), + { 0x0232, 0x03 }, + { 0x02f4, 0x0b }, + { 0x018b, 0x00 }, +}; + +static int si2165_set_frontend_dvbc(struct dvb_frontend *fe) +{ + struct si2165_state *state = fe->demodulator_priv; + int ret; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + const u32 dvb_rate = p->symbol_rate; + const u32 bw_hz = p->bandwidth_hz; + + if (!state->has_dvbc) + return -EINVAL; + + if (dvb_rate == 0) + return -EINVAL; + + ret = si2165_adjust_pll_divl(state, 14); if (ret < 0) return ret; - ret = si2165_writereg8(state, 0x01c8, 0x68); + + /* Oversampling */ + ret = si2165_set_oversamp(state, dvb_rate); if (ret < 0) return ret; - /* freq_sync_range */ - ret = si2165_writereg16(state, 0x030c, 0x0064); + + ret = si2165_writereg32(state, 0x00c4, bw_hz); if (ret < 0) return ret; - /* gp_reg0 */ - ret = si2165_readreg8(state, 0x0387, val); + + ret = si2165_write_reg_list(state, dvbc_regs, ARRAY_SIZE(dvbc_regs)); if (ret < 0) return ret; - ret = si2165_writereg8(state, 0x0387, 0x00); + + return 0; +} + +static const struct si2165_reg_value_pair agc_rewrite[] = { + { 0x012a, 0x46 }, + { 0x012c, 0x00 }, + { 0x012e, 0x0a }, + { 0x012f, 0xff }, + { 0x0123, 0x70 } +}; + +static int si2165_set_frontend(struct dvb_frontend *fe) +{ + struct si2165_state *state = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + u32 delsys = p->delivery_system; + int ret; + u8 val[3]; + + /* initial setting of if freq shift */ + ret = si2165_set_if_freq_shift(state); if (ret < 0) return ret; + + switch (delsys) { + case SYS_DVBT: + ret = si2165_set_frontend_dvbt(fe); + if (ret < 0) + return ret; + break; + case SYS_DVBC_ANNEX_A: + ret = si2165_set_frontend_dvbc(fe); + if (ret < 0) + return ret; + break; + default: + return -EINVAL; + } + /* dsp_addr_jump */ ret = si2165_writereg32(state, 0x0348, 0xf4000000); if (ret < 0) @@ -874,8 +968,7 @@ static int si2165_set_parameters(struct dvb_frontend *fe) fe->ops.tuner_ops.set_params(fe); /* recalc if_freq_shift if IF might has changed */ - fe->ops.tuner_ops.get_if_frequency(fe, &IF); - ret = si2165_set_if_freq_shift(state, IF); + ret = si2165_set_if_freq_shift(state); if (ret < 0) return ret; @@ -886,6 +979,7 @@ static int si2165_set_parameters(struct dvb_frontend *fe) ret = si2165_writereg8(state, 0x0341, 0x00); if (ret < 0) return ret; + /* reset all */ ret = si2165_writereg8(state, 0x00c0, 0x00); if (ret < 0) @@ -894,6 +988,13 @@ static int si2165_set_parameters(struct dvb_frontend *fe) ret = si2165_writereg32(state, 0x0384, 0x00000000); if (ret < 0) return ret; + + /* write adc values after each reset*/ + ret = si2165_write_reg_list(state, agc_rewrite, + ARRAY_SIZE(agc_rewrite)); + if (ret < 0) + return ret; + /* start_synchro */ ret = si2165_writereg8(state, 0x02e0, 0x01); if (ret < 0) @@ -917,7 +1018,12 @@ static void si2165_release(struct dvb_frontend *fe) static struct dvb_frontend_ops si2165_ops = { .info = { .name = "Silicon Labs ", - .caps = FE_CAN_FEC_1_2 | + /* For DVB-C */ + .symbol_rate_min = 1000000, + .symbol_rate_max = 7200000, + /* For DVB-T */ + .frequency_stepsize = 166667, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | @@ -930,7 +1036,6 @@ static struct dvb_frontend_ops si2165_ops = { FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | FE_CAN_MUTE_TS | @@ -943,7 +1048,7 @@ static struct dvb_frontend_ops si2165_ops = { .init = si2165_init, .sleep = si2165_sleep, - .set_frontend = si2165_set_parameters, + .set_frontend = si2165_set_frontend, .read_status = si2165_read_status, .release = si2165_release, @@ -979,9 +1084,9 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config, } /* create dvb_frontend */ - memcpy(&state->frontend.ops, &si2165_ops, + memcpy(&state->fe.ops, &si2165_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; + state->fe.demodulator_priv = state; /* powerup */ io_ret = si2165_writereg8(state, 0x0000, state->config.chip_mode); @@ -1033,20 +1138,22 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config, KBUILD_MODNAME, chip_name, rev_char, state->chip_type, state->chip_revcode); - strlcat(state->frontend.ops.info.name, chip_name, - sizeof(state->frontend.ops.info.name)); + strlcat(state->fe.ops.info.name, chip_name, + sizeof(state->fe.ops.info.name)); n = 0; if (state->has_dvbt) { - state->frontend.ops.delsys[n++] = SYS_DVBT; - strlcat(state->frontend.ops.info.name, " DVB-T", - sizeof(state->frontend.ops.info.name)); + state->fe.ops.delsys[n++] = SYS_DVBT; + strlcat(state->fe.ops.info.name, " DVB-T", + sizeof(state->fe.ops.info.name)); + } + if (state->has_dvbc) { + state->fe.ops.delsys[n++] = SYS_DVBC_ANNEX_A; + strlcat(state->fe.ops.info.name, " DVB-C", + sizeof(state->fe.ops.info.name)); } - if (state->has_dvbc) - dev_warn(&state->i2c->dev, "%s: DVB-C is not yet supported.\n", - KBUILD_MODNAME); - return &state->frontend; + return &state->fe; error: kfree(state); diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c index 4ef8a5c7003e..c978c801c7aa 100644 --- a/drivers/media/dvb-frontends/stb6100.c +++ b/drivers/media/dvb-frontends/stb6100.c @@ -252,6 +252,7 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) { int rc; u8 f; + u32 bw; struct stb6100_state *state = fe->tuner_priv; rc = stb6100_read_reg(state, STB6100_F); @@ -259,9 +260,9 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return rc; f = rc & STB6100_F_F; - state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */ + bw = (f + 5) * 2000; /* x2 for ZIF */ - *bandwidth = state->bandwidth = state->status.bandwidth * 1000; + *bandwidth = state->bandwidth = bw * 1000; dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth); return 0; } @@ -495,68 +496,28 @@ static int stb6100_sleep(struct dvb_frontend *fe) static int stb6100_init(struct dvb_frontend *fe) { struct stb6100_state *state = fe->tuner_priv; - struct tuner_state *status = &state->status; + int refclk = 27000000; /* Hz */ - status->tunerstep = 125000; - status->ifreq = 0; - status->refclock = 27000000; /* Hz */ - status->iqsense = 1; - status->bandwidth = 36000; /* kHz */ - state->bandwidth = status->bandwidth * 1000; /* Hz */ - state->reference = status->refclock / 1000; /* kHz */ + /* + * iqsense = 1 + * tunerstep = 125000 + */ + state->bandwidth = 36000000; /* Hz */ + state->reference = refclk / 1000; /* kHz */ /* Set default bandwidth. Modified, PN 13-May-10 */ return 0; } -static int stb6100_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) +static int stb6100_set_params(struct dvb_frontend *fe) { - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_get_frequency(fe, &state->frequency); - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_get_bandwidth(fe, &state->bandwidth); - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } + struct dtv_frontend_properties *c = &fe->dtv_property_cache; - return 0; -} + if (c->frequency > 0) + stb6100_set_frequency(fe, c->frequency); -static int stb6100_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - struct stb6100_state *tstate = fe->tuner_priv; - - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_set_frequency(fe, state->frequency); - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_set_bandwidth(fe, state->bandwidth); - tstate->bandwidth = state->bandwidth; - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } + if (c->bandwidth_hz > 0) + stb6100_set_bandwidth(fe, c->bandwidth_hz); return 0; } @@ -572,8 +533,9 @@ static struct dvb_tuner_ops stb6100_ops = { .init = stb6100_init, .sleep = stb6100_sleep, .get_status = stb6100_get_status, - .get_state = stb6100_get_state, - .set_state = stb6100_set_state, + .set_params = stb6100_set_params, + .get_frequency = stb6100_get_frequency, + .get_bandwidth = stb6100_get_bandwidth, .release = stb6100_release }; diff --git a/drivers/media/dvb-frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h index 218c8188865d..f7b468b6dc26 100644 --- a/drivers/media/dvb-frontends/stb6100.h +++ b/drivers/media/dvb-frontends/stb6100.h @@ -86,7 +86,6 @@ struct stb6100_state { const struct stb6100_config *config; struct dvb_tuner_ops ops; struct dvb_frontend *frontend; - struct tuner_state status; u32 frequency; u32 srate; diff --git a/drivers/media/dvb-frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h index 6edc15365847..2ef67aa768b9 100644 --- a/drivers/media/dvb-frontends/stb6100_cfg.h +++ b/drivers/media/dvb-frontends/stb6100_cfg.h @@ -19,20 +19,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/dvb/frontend.h> +#include "dvb_frontend.h" + static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; int err = 0; - if (tuner_ops->get_state) { - err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state); + if (tuner_ops->get_frequency) { + err = tuner_ops->get_frequency(fe, frequency); if (err < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - *frequency = t_state.frequency; } return 0; } @@ -41,13 +42,16 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 bw = c->bandwidth_hz; int err = 0; - t_state.frequency = frequency; + c->frequency = frequency; + c->bandwidth_hz = 0; /* Don't adjust the bandwidth */ - if (tuner_ops->set_state) { - err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state); + if (tuner_ops->set_params) { + err = tuner_ops->set_params(fe); + c->bandwidth_hz = bw; if (err < 0) { printk("%s: Invalid parameter\n", __func__); return err; @@ -60,16 +64,14 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; int err = 0; - if (tuner_ops->get_state) { - err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state); + if (tuner_ops->get_bandwidth) { + err = tuner_ops->get_bandwidth(fe, bandwidth); if (err < 0) { printk("%s: Invalid parameter\n", __func__); return err; } - *bandwidth = t_state.bandwidth; } return 0; } @@ -78,13 +80,16 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 freq = c->frequency; int err = 0; - t_state.bandwidth = bandwidth; + c->bandwidth_hz = bandwidth; + c->frequency = 0; /* Don't adjust the frequency */ - if (tuner_ops->set_state) { - err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state); + if (tuner_ops->set_params) { + err = tuner_ops->set_params(fe); + c->frequency = freq; if (err < 0) { printk("%s: Invalid parameter\n", __func__); return err; diff --git a/drivers/media/dvb-frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h index bd8a0ec9e2cc..50ffa21e3871 100644 --- a/drivers/media/dvb-frontends/stb6100_proc.h +++ b/drivers/media/dvb-frontends/stb6100_proc.h @@ -17,27 +17,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <linux/dvb/frontend.h> +#include "dvb_frontend.h" + static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state state; int err = 0; - if (tuner_ops->get_state) { + if (tuner_ops->get_frequency) { if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 1); - err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state); + err = tuner_ops->get_frequency(fe, frequency); if (err < 0) { - printk(KERN_ERR "%s: Invalid parameter\n", __func__); + printk("%s: Invalid parameter\n", __func__); return err; } if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 0); - - *frequency = state.frequency; } return 0; @@ -47,18 +47,21 @@ static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state state; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 bw = c->bandwidth_hz; int err = 0; - state.frequency = frequency; + c->frequency = frequency; + c->bandwidth_hz = 0; /* Don't adjust the bandwidth */ - if (tuner_ops->set_state) { + if (tuner_ops->set_params) { if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 1); - err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state); + err = tuner_ops->set_params(fe); + c->bandwidth_hz = bw; if (err < 0) { - printk(KERN_ERR "%s: Invalid parameter\n", __func__); + printk("%s: Invalid parameter\n", __func__); return err; } @@ -74,14 +77,13 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state state; int err = 0; - if (tuner_ops->get_state) { + if (tuner_ops->get_bandwidth) { if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 1); - err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state); + err = tuner_ops->get_bandwidth(fe, bandwidth); if (err < 0) { printk(KERN_ERR "%s: Invalid parameter\n", __func__); return err; @@ -89,8 +91,6 @@ static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth) if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 0); - - *bandwidth = state.bandwidth; } return 0; @@ -100,16 +100,19 @@ static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state state; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + u32 freq = c->frequency; int err = 0; - state.bandwidth = bandwidth; + c->bandwidth_hz = bandwidth; + c->frequency = 0; /* Don't adjust the frequency */ - if (tuner_ops->set_state) { + if (tuner_ops->set_params) { if (frontend_ops->i2c_gate_ctrl) frontend_ops->i2c_gate_ctrl(fe, 1); - err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state); + err = tuner_ops->set_params(fe); + c->frequency = freq; if (err < 0) { printk(KERN_ERR "%s: Invalid parameter\n", __func__); return err; diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c index 63cc12378d9a..82f8cc534f33 100644 --- a/drivers/media/dvb-frontends/tda665x.c +++ b/drivers/media/dvb-frontends/tda665x.c @@ -66,26 +66,13 @@ exit: return err; } -static int tda665x_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) +static int tda665x_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tda665x_state *state = fe->tuner_priv; - int err = 0; - switch (param) { - case DVBFE_TUNER_FREQUENCY: - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_BANDWIDTH: - break; - default: - printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); - err = -EINVAL; - break; - } + *frequency = state->frequency; - return err; + return 0; } static int tda665x_get_status(struct dvb_frontend *fe, u32 *status) @@ -111,9 +98,8 @@ exit: return err; } -static int tda665x_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) +static int tda665x_set_frequency(struct dvb_frontend *fe, + u32 new_frequency) { struct tda665x_state *state = fe->tuner_priv; const struct tda665x_config *config = state->config; @@ -121,88 +107,96 @@ static int tda665x_set_state(struct dvb_frontend *fe, u8 buf[4]; int err = 0; - if (param & DVBFE_TUNER_FREQUENCY) { - - frequency = tstate->frequency; - if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) { - printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); - return -EINVAL; - } - - frequency += config->frequency_offst; - frequency *= config->ref_multiplier; - frequency += config->ref_divider >> 1; - frequency /= config->ref_divider; - - buf[0] = (u8) ((frequency & 0x7f00) >> 8); - buf[1] = (u8) (frequency & 0x00ff) >> 0; - buf[2] = 0x80 | 0x40 | 0x02; - buf[3] = 0x00; - - /* restore frequency */ - frequency = tstate->frequency; - - if (frequency < 153000000) { - /* VHF-L */ - buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */ - if (frequency < 68000000) - buf[3] |= 0x40; /* 83uA */ - if (frequency < 1040000000) - buf[3] |= 0x60; /* 122uA */ - if (frequency < 1250000000) - buf[3] |= 0x80; /* 163uA */ - else - buf[3] |= 0xa0; /* 254uA */ - } else if (frequency < 438000000) { - /* VHF-H */ - buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */ - if (frequency < 230000000) - buf[3] |= 0x40; - if (frequency < 300000000) - buf[3] |= 0x60; - else - buf[3] |= 0x80; - } else { - /* UHF */ - buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */ - if (frequency < 470000000) - buf[3] |= 0x60; - if (frequency < 526000000) - buf[3] |= 0x80; - else - buf[3] |= 0xa0; - } - - /* Set params */ - err = tda665x_write(state, buf, 5); - if (err < 0) - goto exit; - - /* sleep for some time */ - printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__); - msleep(20); - /* check status */ - err = tda665x_get_status(fe, &status); - if (err < 0) - goto exit; - - if (status == 1) { - printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status); - state->frequency = frequency; /* cache successful state */ - } else { - printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status); - } - } else { - printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param); + if ((new_frequency < config->frequency_max) + || (new_frequency > config->frequency_min)) { + printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", + __func__, new_frequency); return -EINVAL; } + frequency = new_frequency; + + frequency += config->frequency_offst; + frequency *= config->ref_multiplier; + frequency += config->ref_divider >> 1; + frequency /= config->ref_divider; + + buf[0] = (u8) ((frequency & 0x7f00) >> 8); + buf[1] = (u8) (frequency & 0x00ff) >> 0; + buf[2] = 0x80 | 0x40 | 0x02; + buf[3] = 0x00; + + /* restore frequency */ + frequency = new_frequency; + + if (frequency < 153000000) { + /* VHF-L */ + buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */ + if (frequency < 68000000) + buf[3] |= 0x40; /* 83uA */ + if (frequency < 1040000000) + buf[3] |= 0x60; /* 122uA */ + if (frequency < 1250000000) + buf[3] |= 0x80; /* 163uA */ + else + buf[3] |= 0xa0; /* 254uA */ + } else if (frequency < 438000000) { + /* VHF-H */ + buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */ + if (frequency < 230000000) + buf[3] |= 0x40; + if (frequency < 300000000) + buf[3] |= 0x60; + else + buf[3] |= 0x80; + } else { + /* UHF */ + buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */ + if (frequency < 470000000) + buf[3] |= 0x60; + if (frequency < 526000000) + buf[3] |= 0x80; + else + buf[3] |= 0xa0; + } + + /* Set params */ + err = tda665x_write(state, buf, 5); + if (err < 0) + goto exit; + + /* sleep for some time */ + printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__); + msleep(20); + /* check status */ + err = tda665x_get_status(fe, &status); + if (err < 0) + goto exit; + + if (status == 1) { + printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", + __func__, status); + state->frequency = frequency; /* cache successful state */ + } else { + printk(KERN_ERR "%s: No Phase lock: status=%d\n", + __func__, status); + } + return 0; exit: printk(KERN_ERR "%s: I/O Error\n", __func__); return err; } +static int tda665x_set_params(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *c = &fe->dtv_property_cache; + + tda665x_set_frequency(fe, c->frequency); + + return 0; +} + static int tda665x_release(struct dvb_frontend *fe) { struct tda665x_state *state = fe->tuner_priv; @@ -213,10 +207,9 @@ static int tda665x_release(struct dvb_frontend *fe) } static struct dvb_tuner_ops tda665x_ops = { - - .set_state = tda665x_set_state, - .get_state = tda665x_get_state, .get_status = tda665x_get_status, + .set_params = tda665x_set_params, + .get_frequency = tda665x_get_frequency, .release = tda665x_release }; diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c index 19c488814e5c..3285b1bc4642 100644 --- a/drivers/media/dvb-frontends/tda8261.c +++ b/drivers/media/dvb-frontends/tda8261.c @@ -83,88 +83,71 @@ static int tda8261_get_status(struct dvb_frontend *fe, u32 *status) static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */ static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 }; -static int tda8261_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) +static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct tda8261_state *state = fe->tuner_priv; - int err = 0; - switch (param) { - case DVBFE_TUNER_FREQUENCY: - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_BANDWIDTH: - tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */ - break; - default: - pr_err("%s: Unknown parameter (param=%d)\n", __func__, param); - err = -EINVAL; - break; - } + *frequency = state->frequency; - return err; + return 0; } -static int tda8261_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) +static int tda8261_set_params(struct dvb_frontend *fe) { + struct dtv_frontend_properties *c = &fe->dtv_property_cache; struct tda8261_state *state = fe->tuner_priv; const struct tda8261_config *config = state->config; u32 frequency, N, status = 0; u8 buf[4]; int err = 0; - if (param & DVBFE_TUNER_FREQUENCY) { - /** - * N = Max VCO Frequency / Channel Spacing - * Max VCO Frequency = VCO frequency + (channel spacing - 1) - * (to account for half channel spacing on either side) - */ - frequency = tstate->frequency; - if ((frequency < 950000) || (frequency > 2150000)) { - pr_warn("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); - return -EINVAL; - } - N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; - pr_debug("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n", - __func__, config->step_size, div_tab[config->step_size], N, N); - - buf[0] = (N >> 8) & 0xff; - buf[1] = N & 0xff; - buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1); - - if (frequency < 1450000) - buf[3] = 0x00; - else if (frequency < 2000000) - buf[3] = 0x40; - else if (frequency < 2150000) - buf[3] = 0x80; - - /* Set params */ - if ((err = tda8261_write(state, buf)) < 0) { - pr_err("%s: I/O Error\n", __func__); - return err; - } - /* sleep for some time */ - pr_debug("%s: Waiting to Phase LOCK\n", __func__); - msleep(20); - /* check status */ - if ((err = tda8261_get_status(fe, &status)) < 0) { - pr_err("%s: I/O Error\n", __func__); - return err; - } - if (status == 1) { - pr_debug("%s: Tuner Phase locked: status=%d\n", __func__, status); - state->frequency = frequency; /* cache successful state */ - } else { - pr_debug("%s: No Phase lock: status=%d\n", __func__, status); - } - } else { - pr_err("%s: Unknown parameter (param=%d)\n", __func__, param); + /* + * N = Max VCO Frequency / Channel Spacing + * Max VCO Frequency = VCO frequency + (channel spacing - 1) + * (to account for half channel spacing on either side) + */ + frequency = c->frequency; + if ((frequency < 950000) || (frequency > 2150000)) { + pr_warn("%s: Frequency beyond limits, frequency=%d\n", + __func__, frequency); return -EINVAL; } + N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; + pr_debug("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n", + __func__, config->step_size, div_tab[config->step_size], N, N); + + buf[0] = (N >> 8) & 0xff; + buf[1] = N & 0xff; + buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1); + + if (frequency < 1450000) + buf[3] = 0x00; + else if (frequency < 2000000) + buf[3] = 0x40; + else if (frequency < 2150000) + buf[3] = 0x80; + + /* Set params */ + err = tda8261_write(state, buf); + if (err < 0) { + pr_err("%s: I/O Error\n", __func__); + return err; + } + /* sleep for some time */ + pr_debug("%s: Waiting to Phase LOCK\n", __func__); + msleep(20); + /* check status */ + if ((err = tda8261_get_status(fe, &status)) < 0) { + pr_err("%s: I/O Error\n", __func__); + return err; + } + if (status == 1) { + pr_debug("%s: Tuner Phase locked: status=%d\n", __func__, + status); + state->frequency = frequency; /* cache successful state */ + } else { + pr_debug("%s: No Phase lock: status=%d\n", __func__, status); + } return 0; } @@ -182,14 +165,13 @@ static struct dvb_tuner_ops tda8261_ops = { .info = { .name = "TDA8261", -// .tuner_name = NULL, .frequency_min = 950000, .frequency_max = 2150000, .frequency_step = 0 }, - .set_state = tda8261_set_state, - .get_state = tda8261_get_state, + .set_params = tda8261_set_params, + .get_frequency = tda8261_get_frequency, .get_status = tda8261_get_status, .release = tda8261_release }; @@ -210,10 +192,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, fe->ops.tuner_ops = tda8261_ops; fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size]; -// fe->ops.tuner_ops.tuner_name = &config->buf; -// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n", -// __func__, fe->ops.tuner_ops.tuner_name); pr_info("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__); return fe; diff --git a/drivers/media/dvb-frontends/tda8261_cfg.h b/drivers/media/dvb-frontends/tda8261_cfg.h index 04a19e14ee5a..fe527ff84df4 100644 --- a/drivers/media/dvb-frontends/tda8261_cfg.h +++ b/drivers/media/dvb-frontends/tda8261_cfg.h @@ -21,17 +21,15 @@ static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; int err = 0; - if (tuner_ops->get_state) { - err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state); + if (tuner_ops->get_frequency) { + err = tuner_ops->get_frequency(fe, frequency); if (err < 0) { - printk("%s: Invalid parameter\n", __func__); + pr_err("%s: Invalid parameter\n", __func__); return err; } - *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); + pr_debug("%s: Frequency=%d\n", __func__, *frequency); } return 0; } @@ -40,37 +38,24 @@ static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency) { struct dvb_frontend_ops *frontend_ops = &fe->ops; struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; + struct dtv_frontend_properties *c = &fe->dtv_property_cache; int err = 0; - t_state.frequency = frequency; - - if (tuner_ops->set_state) { - err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state); + if (tuner_ops->set_params) { + err = tuner_ops->set_params(fe); if (err < 0) { - printk("%s: Invalid parameter\n", __func__); + pr_err("%s: Invalid parameter\n", __func__); return err; } } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); + pr_debug("%s: Frequency=%d\n", __func__, c->frequency); return 0; } static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) { - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; + /* FIXME! need to calculate Bandwidth */ + *bandwidth = 40000000; - if (tuner_ops->get_state) { - err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state); - if (err < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *bandwidth = t_state.bandwidth; - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); - } return 0; } diff --git a/drivers/media/dvb-frontends/tdhd1.h b/drivers/media/dvb-frontends/tdhd1.h index 17750985db0c..2b9e8732c802 100644 --- a/drivers/media/dvb-frontends/tdhd1.h +++ b/drivers/media/dvb-frontends/tdhd1.h @@ -20,7 +20,7 @@ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html * * - * The project's page is at http://www.linuxtv.org + * The project's page is at https://linuxtv.org */ #ifndef TDHD1_H |