Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (4846): Create new lgh06xf atsc tuner module

This patch creates a new atsc tuner module for the LG TDVS-H06xF ATSC tuners,
called lgh06xf. The purpose of this change is to reduce some duplicated
code, and to allow the lgh06xf tuner code to take advantage of dvb_attach().
As a side effect, the dependency of dvb-bt8xx on dvb-pll has been removed,
since the lgh06xf module itself will use dvb-pll, while remaining optional
for the dvb-bt8xx driver through the use of DVB_FE_CUSTOMISE
Acked-by: Andrew de Quincey <adq_dvb@lidskialf.net>

Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Michael Krufky and committed by
Mauro Carvalho Chehab
76db93d0 f9a76156

+198 -106
+1
drivers/media/dvb/b2c2/Kconfig
··· 9 9 select DVB_STV0297 if !DVB_FE_CUSTOMISE 10 10 select DVB_BCM3510 if !DVB_FE_CUSTOMISE 11 11 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 12 + select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE 12 13 help 13 14 Support for the digital TV receiver chip made by B2C2 Inc. included in 14 15 Technisats PCI cards and USB boxes.
+2 -8
drivers/media/dvb/b2c2/flexcop-fe-tuner.c
··· 14 14 #include "stv0297.h" 15 15 #include "mt312.h" 16 16 #include "lgdt330x.h" 17 - #include "lg_h06xf.h" 17 + #include "lgh06xf.h" 18 18 #include "dvb-pll.h" 19 19 20 20 /* lnb control */ ··· 303 303 return request_firmware(fw, name, fc->dev); 304 304 } 305 305 306 - static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) 307 - { 308 - struct flexcop_device *fc = fe->dvb->priv; 309 - return lg_h06xf_pll_set(fe, &fc->i2c_adap, params); 310 - } 311 - 312 306 static struct lgdt330x_config air2pc_atsc_hd5000_config = { 313 307 .demod_address = 0x59, 314 308 .demod_chip = LGDT3303, ··· 527 533 /* try the air atsc 3nd generation (lgdt3303) */ 528 534 if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { 529 535 fc->dev_type = FC_AIR_ATSC3; 530 - fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; 536 + dvb_attach(lgh06xf_attach, fc->fe, &fc->i2c_adap); 531 537 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); 532 538 } else 533 539 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
+1 -1
drivers/media/dvb/bt8xx/Kconfig
··· 1 1 config DVB_BT8XX 2 2 tristate "BT8xx based PCI cards" 3 3 depends on DVB_CORE && PCI && I2C && VIDEO_BT848 4 - select DVB_PLL 5 4 select DVB_MT352 if !DVB_FE_CUSTOMISE 6 5 select DVB_SP887X if !DVB_FE_CUSTOMISE 7 6 select DVB_NXT6000 if !DVB_FE_CUSTOMISE 8 7 select DVB_CX24110 if !DVB_FE_CUSTOMISE 9 8 select DVB_OR51211 if !DVB_FE_CUSTOMISE 10 9 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 10 + select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE 11 11 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 12 12 select FW_LOADER 13 13 help
+1 -8
drivers/media/dvb/bt8xx/dvb-bt8xx.c
··· 34 34 #include "dvb_frontend.h" 35 35 #include "dvb-bt8xx.h" 36 36 #include "bt878.h" 37 - #include "dvb-pll.h" 38 37 39 38 static int debug; 40 39 ··· 567 568 .demod_init = digitv_alps_tded4_demod_init, 568 569 }; 569 570 570 - static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 571 - { 572 - struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; 573 - return lg_h06xf_pll_set(fe, card->i2c_adapter, params); 574 - } 575 - 576 571 static struct lgdt330x_config tdvs_tua6034_config = { 577 572 .demod_address = 0x0e, 578 573 .demod_chip = LGDT3303, ··· 609 616 lgdt330x_reset(card); 610 617 card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); 611 618 if (card->fe != NULL) { 612 - card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params; 619 + dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter); 613 620 dprintk ("dvb_bt8xx: lgdt330x detected\n"); 614 621 } 615 622 break;
+1 -1
drivers/media/dvb/bt8xx/dvb-bt8xx.h
··· 37 37 #include "cx24110.h" 38 38 #include "or51211.h" 39 39 #include "lgdt330x.h" 40 - #include "lg_h06xf.h" 40 + #include "lgh06xf.h" 41 41 #include "zl10353.h" 42 42 43 43 struct dvb_bt8xx_card {
+1
drivers/media/dvb/dvb-usb/Kconfig
··· 98 98 depends on DVB_USB 99 99 select DVB_CX22702 if !DVB_FE_CUSTOMISE 100 100 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 101 + select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE 101 102 select DVB_MT352 if !DVB_FE_CUSTOMISE 102 103 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 103 104 help
+2 -9
drivers/media/dvb/dvb-usb/cxusb.c
··· 27 27 28 28 #include "cx22702.h" 29 29 #include "lgdt330x.h" 30 - #include "lg_h06xf.h" 30 + #include "lgh06xf.h" 31 31 #include "mt352.h" 32 32 #include "mt352_priv.h" 33 33 #include "zl10353.h" ··· 324 324 return 0; 325 325 } 326 326 327 - static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe, 328 - struct dvb_frontend_parameters *fep) 329 - { 330 - struct dvb_usb_adapter *adap = fe->dvb->priv; 331 - return lg_h06xf_pll_set(fe, &adap->dev->i2c_adap, fep); 332 - } 333 - 334 327 static struct cx22702_config cxusb_cx22702_config = { 335 328 .demod_address = 0x63, 336 329 ··· 391 398 392 399 static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) 393 400 { 394 - adap->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params; 401 + dvb_attach(lgh06xf_attach, adap->fe, &adap->dev->i2c_adap); 395 402 return 0; 396 403 } 397 404
+8
drivers/media/dvb/frontends/Kconfig
··· 297 297 help 298 298 A driver for the silicon IF tuner MT2060 from Microtune. 299 299 300 + config DVB_TUNER_LGH06XF 301 + tristate "LG TDVS-H06xF ATSC tuner" 302 + depends on DVB_CORE && I2C 303 + select DVB_PLL 304 + default m if DVB_FE_CUSTOMISE 305 + help 306 + A driver for the LG TDVS-H06xF ATSC tuner family. 307 + 300 308 comment "Miscellaneous devices" 301 309 depends on DVB_CORE 302 310
+1
drivers/media/dvb/frontends/Makefile
··· 39 39 obj-$(CONFIG_DVB_TDA826X) += tda826x.o 40 40 obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o 41 41 obj-$(CONFIG_DVB_TUA6100) += tua6100.o 42 + obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
-64
drivers/media/dvb/frontends/lg_h06xf.h
··· 1 - /* 2 - * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF 3 - * 4 - * This program is free software; you can redistribute it and/or modify 5 - * it under the terms of the GNU General Public License as published by 6 - * the Free Software Foundation; either version 2 of the License, or 7 - * (at your option) any later version. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - * 14 - * You should have received a copy of the GNU General Public License 15 - * along with this program; if not, write to the Free Software 16 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 - */ 18 - 19 - #ifndef _LG_H06XF_H_ 20 - #define _LG_H06XF_H_ 21 - #include "dvb-pll.h" 22 - 23 - static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, 24 - struct dvb_frontend_parameters* params) 25 - { 26 - u8 buf[4]; 27 - struct i2c_msg msg = { .addr = 0x61, .flags = 0, 28 - .buf = buf, .len = sizeof(buf) }; 29 - int err; 30 - 31 - dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); 32 - if (fe->ops.i2c_gate_ctrl) 33 - fe->ops.i2c_gate_ctrl(fe, 1); 34 - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { 35 - printk(KERN_WARNING "lg_h06xf: %s error " 36 - "(addr %02x <- %02x, err = %i)\n", 37 - __FUNCTION__, buf[0], buf[1], err); 38 - if (err < 0) 39 - return err; 40 - else 41 - return -EREMOTEIO; 42 - } 43 - 44 - /* Set the Auxiliary Byte. */ 45 - buf[0] = buf[2]; 46 - buf[0] &= ~0x20; 47 - buf[0] |= 0x18; 48 - buf[1] = 0x50; 49 - msg.len = 2; 50 - if (fe->ops.i2c_gate_ctrl) 51 - fe->ops.i2c_gate_ctrl(fe, 1); 52 - if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { 53 - printk(KERN_WARNING "lg_h06xf: %s error " 54 - "(addr %02x <- %02x, err = %i)\n", 55 - __FUNCTION__, buf[0], buf[1], err); 56 - if (err < 0) 57 - return err; 58 - else 59 - return -EREMOTEIO; 60 - } 61 - 62 - return 0; 63 - } 64 - #endif
+139
drivers/media/dvb/frontends/lgh06xf.c
··· 1 + /* 2 + * lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 + */ 18 + 19 + #include "dvb-pll.h" 20 + #include "lgh06xf.h" 21 + 22 + #define LG_H06XF_PLL_I2C_ADDR 0x61 23 + 24 + struct lgh06xf_priv { 25 + struct i2c_adapter *i2c; 26 + u32 frequency; 27 + }; 28 + 29 + static int lgh06xf_release(struct dvb_frontend *fe) 30 + { 31 + kfree(fe->tuner_priv); 32 + fe->tuner_priv = NULL; 33 + return 0; 34 + } 35 + 36 + static int lgh06xf_set_params(struct dvb_frontend* fe, 37 + struct dvb_frontend_parameters* params) 38 + { 39 + struct lgh06xf_priv *priv = fe->tuner_priv; 40 + u8 buf[4]; 41 + struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0, 42 + .buf = buf, .len = sizeof(buf) }; 43 + u32 div; 44 + int i; 45 + int err; 46 + 47 + dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); 48 + if (fe->ops.i2c_gate_ctrl) 49 + fe->ops.i2c_gate_ctrl(fe, 1); 50 + if ((err = i2c_transfer(priv->i2c, &msg, 1)) != 1) { 51 + printk(KERN_WARNING "lgh06xf: %s error " 52 + "(addr %02x <- %02x, err = %i)\n", 53 + __FUNCTION__, buf[0], buf[1], err); 54 + if (err < 0) 55 + return err; 56 + else 57 + return -EREMOTEIO; 58 + } 59 + 60 + /* Set the Auxiliary Byte. */ 61 + buf[0] = buf[2]; 62 + buf[0] &= ~0x20; 63 + buf[0] |= 0x18; 64 + buf[1] = 0x50; 65 + msg.len = 2; 66 + if (fe->ops.i2c_gate_ctrl) 67 + fe->ops.i2c_gate_ctrl(fe, 1); 68 + if ((err = i2c_transfer(priv->i2c, &msg, 1)) != 1) { 69 + printk(KERN_WARNING "lgh06xf: %s error " 70 + "(addr %02x <- %02x, err = %i)\n", 71 + __FUNCTION__, buf[0], buf[1], err); 72 + if (err < 0) 73 + return err; 74 + else 75 + return -EREMOTEIO; 76 + } 77 + 78 + // calculate the frequency we set it to 79 + for (i = 0; i < dvb_pll_lg_tdvs_h06xf.count; i++) { 80 + if (params->frequency > dvb_pll_lg_tdvs_h06xf.entries[i].limit) 81 + continue; 82 + break; 83 + } 84 + div = (params->frequency + dvb_pll_lg_tdvs_h06xf.entries[i].offset) / 85 + dvb_pll_lg_tdvs_h06xf.entries[i].stepsize; 86 + priv->frequency = (div * dvb_pll_lg_tdvs_h06xf.entries[i].stepsize) - 87 + dvb_pll_lg_tdvs_h06xf.entries[i].offset; 88 + 89 + return 0; 90 + } 91 + 92 + static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency) 93 + { 94 + struct lgh06xf_priv *priv = fe->tuner_priv; 95 + *frequency = priv->frequency; 96 + return 0; 97 + } 98 + 99 + static struct dvb_tuner_ops lgh06xf_tuner_ops = { 100 + .release = lgh06xf_release, 101 + .set_params = lgh06xf_set_params, 102 + .get_frequency = lgh06xf_get_frequency, 103 + }; 104 + 105 + struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe, 106 + struct i2c_adapter *i2c) 107 + { 108 + struct lgh06xf_priv *priv = NULL; 109 + 110 + priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL); 111 + if (priv == NULL) 112 + return NULL; 113 + 114 + priv->i2c = i2c; 115 + 116 + memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops, 117 + sizeof(struct dvb_tuner_ops)); 118 + 119 + strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name, 120 + sizeof(fe->ops.tuner_ops.info.name)); 121 + 122 + fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min; 123 + fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max; 124 + 125 + fe->tuner_priv = priv; 126 + return fe; 127 + } 128 + 129 + EXPORT_SYMBOL(lgh06xf_attach); 130 + 131 + MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support"); 132 + MODULE_AUTHOR("Michael Krufky"); 133 + MODULE_LICENSE("GPL"); 134 + 135 + /* 136 + * Local variables: 137 + * c-basic-offset: 8 138 + * End: 139 + */
+35
drivers/media/dvb/frontends/lgh06xf.h
··· 1 + /* 2 + * lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License 15 + * along with this program; if not, write to the Free Software 16 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 + */ 18 + 19 + #ifndef _LGH06XF_H_ 20 + #define _LGH06XF_H_ 21 + #include "dvb_frontend.h" 22 + 23 + #if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE)) 24 + extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, 25 + struct i2c_adapter *i2c); 26 + #else 27 + static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, 28 + struct i2c_adapter *i2c); 29 + { 30 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); 31 + return NULL; 32 + } 33 + #endif /* CONFIG_DVB_TUNER_LGH06XF */ 34 + 35 + #endif /* _LGH06XF_H_ */
+1
drivers/media/video/cx88/Kconfig
··· 53 53 select DVB_OR51132 if !DVB_FE_CUSTOMISE 54 54 select DVB_CX22702 if !DVB_FE_CUSTOMISE 55 55 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 56 + select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE 56 57 select DVB_NXT200X if !DVB_FE_CUSTOMISE 57 58 select DVB_CX24123 if !DVB_FE_CUSTOMISE 58 59 select DVB_ISL6421 if !DVB_FE_CUSTOMISE
+5 -15
drivers/media/video/cx88/cx88-dvb.c
··· 42 42 #include "cx22702.h" 43 43 #include "or51132.h" 44 44 #include "lgdt330x.h" 45 - #include "lg_h06xf.h" 45 + #include "lgh06xf.h" 46 46 #include "nxt200x.h" 47 47 #include "cx24123.h" 48 48 #include "isl6421.h" ··· 392 392 return 0; 393 393 } 394 394 395 - static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, 396 - struct dvb_frontend_parameters* params) 397 - { 398 - struct cx8802_dev *dev= fe->dvb->priv; 399 - struct cx88_core *core = dev->core; 400 - 401 - /* Put the analog decoder in standby to keep it quiet */ 402 - cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 403 - 404 - return lg_h06xf_pll_set(fe, &core->i2c_adap, params); 405 - } 406 - 407 395 static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) 408 396 { 409 397 struct cx8802_dev *dev= fe->dvb->priv; ··· 707 719 &fusionhdtv_5_gold, 708 720 &dev->core->i2c_adap); 709 721 if (dev->dvb.frontend != NULL) { 710 - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; 722 + dvb_attach(lgh06xf_attach, dev->dvb.frontend, 723 + &dev->core->i2c_adap); 711 724 } 712 725 } 713 726 break; ··· 726 737 &pchdtv_hd5500, 727 738 &dev->core->i2c_adap); 728 739 if (dev->dvb.frontend != NULL) { 729 - dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; 740 + dvb_attach(lgh06xf_attach, dev->dvb.frontend, 741 + &dev->core->i2c_adap); 730 742 } 731 743 } 732 744 break;