aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew de Quincey <adq_dvb@lidskialf.net>2006-05-12 19:31:51 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-06-25 01:00:21 -0400
commitcd20ca9f194323c74ecccf15a3f5ff6c44effe69 (patch)
tree36e8ad6eab353a34dec9713f9bfbfb7c5060a844
parent9a10655ffa20b596fd162b1c96301f3bed752918 (diff)
V4L/DVB (4012): Fix cx24123 diseqc
Rework diseqc support to be more in line with the other demod drivers. Fix Nova-S-Plus/Nova-SE2 diseqc. Cleanup API. Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/dvb/frontends/cx24123.c184
-rw-r--r--drivers/media/dvb/frontends/cx24123.h9
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c24
-rw-r--r--drivers/media/video/cx88/cx88.h1
5 files changed, 68 insertions, 152 deletions
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index aa3fd8e6cef7..c71422964064 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -48,7 +48,6 @@ struct cx24123_state
48 48
49 u32 lastber; 49 u32 lastber;
50 u16 snr; 50 u16 snr;
51 u8 lnbreg;
52 51
53 /* Some PLL specifics for tuning */ 52 /* Some PLL specifics for tuning */
54 u32 VCAarg; 53 u32 VCAarg;
@@ -249,29 +248,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
249 return 0; 248 return 0;
250} 249}
251 250
252static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
253{
254 u8 buf[] = { reg, data };
255 /* fixme: put the intersil addr int the config */
256 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
257 int err;
258
259 if (debug>1)
260 printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
261 __FUNCTION__,reg, data);
262
263 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
264 printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
265 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
266 return -EREMOTEIO;
267 }
268
269 /* cache the write, no way to read back */
270 state->lnbreg = data;
271
272 return 0;
273}
274
275static int cx24123_readreg(struct cx24123_state* state, u8 reg) 251static int cx24123_readreg(struct cx24123_state* state, u8 reg)
276{ 252{
277 int ret; 253 int ret;
@@ -295,11 +271,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
295 return b1[0]; 271 return b1[0];
296} 272}
297 273
298static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
299{
300 return state->lnbreg;
301}
302
303static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) 274static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
304{ 275{
305 u8 nom_reg = cx24123_readreg(state, 0x0e); 276 u8 nom_reg = cx24123_readreg(state, 0x0e);
@@ -687,10 +658,6 @@ static int cx24123_initfe(struct dvb_frontend* fe)
687 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) 658 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
688 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); 659 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
689 660
690 /* Configure the LNB for 14V */
691 if (state->config->use_isl6421)
692 cx24123_writelnbreg(state, 0x0, 0x2a);
693
694 return 0; 661 return 0;
695} 662}
696 663
@@ -699,50 +666,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
699 struct cx24123_state *state = fe->demodulator_priv; 666 struct cx24123_state *state = fe->demodulator_priv;
700 u8 val; 667 u8 val;
701 668
702 switch (state->config->use_isl6421) { 669 val = cx24123_readreg(state, 0x29) & ~0x40;
703
704 case 1:
705 670
706 val = cx24123_readlnbreg(state, 0x0); 671 switch (voltage) {
707 672 case SEC_VOLTAGE_13:
708 switch (voltage) { 673 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
709 case SEC_VOLTAGE_13: 674 return cx24123_writereg(state, 0x29, val | 0x80);
710 dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); 675 case SEC_VOLTAGE_18:
711 return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ 676 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
712 case SEC_VOLTAGE_18: 677 return cx24123_writereg(state, 0x29, val & 0x7f);
713 dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); 678 default:
714 return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ 679 return -EINVAL;
715 case SEC_VOLTAGE_OFF: 680 };
716 dprintk("%s: isl5421 voltage off\n",__FUNCTION__);
717 return cx24123_writelnbreg(state, 0x0, val & 0x30);
718 default:
719 return -EINVAL;
720 };
721
722 case 0:
723
724 val = cx24123_readreg(state, 0x29);
725
726 switch (voltage) {
727 case SEC_VOLTAGE_13:
728 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
729 if (state->config->enable_lnb_voltage)
730 state->config->enable_lnb_voltage(fe, 1);
731 return cx24123_writereg(state, 0x29, val | 0x80);
732 case SEC_VOLTAGE_18:
733 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
734 if (state->config->enable_lnb_voltage)
735 state->config->enable_lnb_voltage(fe, 1);
736 return cx24123_writereg(state, 0x29, val & 0x7f);
737 case SEC_VOLTAGE_OFF:
738 dprintk("%s: setting voltage off\n", __FUNCTION__);
739 if (state->config->enable_lnb_voltage)
740 state->config->enable_lnb_voltage(fe, 0);
741 return 0;
742 default:
743 return -EINVAL;
744 };
745 }
746 681
747 return 0; 682 return 0;
748} 683}
@@ -763,27 +698,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
763static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) 698static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
764{ 699{
765 struct cx24123_state *state = fe->demodulator_priv; 700 struct cx24123_state *state = fe->demodulator_priv;
766 int i, val; 701 int i, val, tone;
767 702
768 dprintk("%s:\n",__FUNCTION__); 703 dprintk("%s:\n",__FUNCTION__);
769 704
770 /* check if continuous tone has been stopped */ 705 /* stop continuous tone if enabled */
771 if (state->config->use_isl6421) 706 tone = cx24123_readreg(state, 0x29);
772 val = cx24123_readlnbreg(state, 0x00) & 0x10; 707 if (tone & 0x10)
773 else 708 cx24123_writereg(state, 0x29, tone & ~0x50);
774 val = cx24123_readreg(state, 0x29) & 0x10;
775
776
777 if (val) {
778 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
779 return -ENOTSUPP;
780 }
781 709
782 /* wait for diseqc queue ready */ 710 /* wait for diseqc queue ready */
783 cx24123_wait_for_diseqc(state); 711 cx24123_wait_for_diseqc(state);
784 712
785 /* select tone mode */ 713 /* select tone mode */
786 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); 714 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
787 715
788 for (i = 0; i < cmd->msg_len; i++) 716 for (i = 0; i < cmd->msg_len; i++)
789 cx24123_writereg(state, 0x2C + i, cmd->msg[i]); 717 cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
@@ -794,36 +722,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
794 /* wait for diseqc message to finish sending */ 722 /* wait for diseqc message to finish sending */
795 cx24123_wait_for_diseqc(state); 723 cx24123_wait_for_diseqc(state);
796 724
725 /* restart continuous tone if enabled */
726 if (tone & 0x10) {
727 cx24123_writereg(state, 0x29, tone & ~0x40);
728 }
729
797 return 0; 730 return 0;
798} 731}
799 732
800static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 733static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
801{ 734{
802 struct cx24123_state *state = fe->demodulator_priv; 735 struct cx24123_state *state = fe->demodulator_priv;
803 int val; 736 int val, tone;
804 737
805 dprintk("%s:\n", __FUNCTION__); 738 dprintk("%s:\n", __FUNCTION__);
806 739
807 /* check if continuous tone has been stoped */ 740 /* stop continuous tone if enabled */
808 if (state->config->use_isl6421) 741 tone = cx24123_readreg(state, 0x29);
809 val = cx24123_readlnbreg(state, 0x00) & 0x10; 742 if (tone & 0x10)
810 else 743 cx24123_writereg(state, 0x29, tone & ~0x50);
811 val = cx24123_readreg(state, 0x29) & 0x10;
812
813
814 if (val) {
815 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
816 return -ENOTSUPP;
817 }
818 744
745 /* wait for diseqc queue ready */
819 cx24123_wait_for_diseqc(state); 746 cx24123_wait_for_diseqc(state);
820 747
821 /* select tone mode */ 748 /* select tone mode */
822 val = cx24123_readreg(state, 0x2a) & 0xf8; 749 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
823 cx24123_writereg(state, 0x2a, val | 0x04); 750 msleep(30);
824
825 val = cx24123_readreg(state, 0x29); 751 val = cx24123_readreg(state, 0x29);
826
827 if (burst == SEC_MINI_A) 752 if (burst == SEC_MINI_A)
828 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); 753 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
829 else if (burst == SEC_MINI_B) 754 else if (burst == SEC_MINI_B)
@@ -832,7 +757,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
832 return -EINVAL; 757 return -EINVAL;
833 758
834 cx24123_wait_for_diseqc(state); 759 cx24123_wait_for_diseqc(state);
760 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
835 761
762 /* restart continuous tone if enabled */
763 if (tone & 0x10) {
764 cx24123_writereg(state, 0x29, tone & ~0x40);
765 }
836 return 0; 766 return 0;
837} 767}
838 768
@@ -973,38 +903,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
973 struct cx24123_state *state = fe->demodulator_priv; 903 struct cx24123_state *state = fe->demodulator_priv;
974 u8 val; 904 u8 val;
975 905
976 switch (state->config->use_isl6421) { 906 /* wait for diseqc queue ready */
977 case 1: 907 cx24123_wait_for_diseqc(state);
978
979 val = cx24123_readlnbreg(state, 0x0);
980
981 switch (tone) {
982 case SEC_TONE_ON:
983 dprintk("%s: isl6421 sec tone on\n",__FUNCTION__);
984 return cx24123_writelnbreg(state, 0x0, val | 0x10);
985 case SEC_TONE_OFF:
986 dprintk("%s: isl6421 sec tone off\n",__FUNCTION__);
987 return cx24123_writelnbreg(state, 0x0, val & 0x2f);
988 default:
989 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
990 return -EINVAL;
991 }
992
993 case 0:
994 908
995 val = cx24123_readreg(state, 0x29); 909 val = cx24123_readreg(state, 0x29) & ~0x40;
996 910
997 switch (tone) { 911 switch (tone) {
998 case SEC_TONE_ON: 912 case SEC_TONE_ON:
999 dprintk("%s: setting tone on\n", __FUNCTION__); 913 dprintk("%s: setting tone on\n", __FUNCTION__);
1000 return cx24123_writereg(state, 0x29, val | 0x10); 914 return cx24123_writereg(state, 0x29, val | 0x10);
1001 case SEC_TONE_OFF: 915 case SEC_TONE_OFF:
1002 dprintk("%s: setting tone off\n",__FUNCTION__); 916 dprintk("%s: setting tone off\n",__FUNCTION__);
1003 return cx24123_writereg(state, 0x29, val & 0xef); 917 return cx24123_writereg(state, 0x29, val & 0xef);
1004 default: 918 default:
1005 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); 919 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
1006 return -EINVAL; 920 return -EINVAL;
1007 }
1008 } 921 }
1009 922
1010 return 0; 923 return 0;
@@ -1040,7 +953,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1040 memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); 953 memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
1041 state->lastber = 0; 954 state->lastber = 0;
1042 state->snr = 0; 955 state->snr = 0;
1043 state->lnbreg = 0;
1044 state->VCAarg = 0; 956 state->VCAarg = 0;
1045 state->VGAarg = 0; 957 state->VGAarg = 0;
1046 state->bandselectarg = 0; 958 state->bandselectarg = 0;
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 7ec4ee856014..9606f825935c 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -28,17 +28,8 @@ struct cx24123_config
28 /* the demodulator's i2c address */ 28 /* the demodulator's i2c address */
29 u8 demod_address; 29 u8 demod_address;
30 30
31 /*
32 cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
33 for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
34 from register 0x29 of the CX24123 demodulator
35 */
36 int use_isl6421;
37
38 /* Need to set device param for start_dma */ 31 /* Need to set device param for start_dma */
39 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
40
41 void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
42}; 33};
43 34
44extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, 35extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 630273992a41..c092d2219f0b 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,6 +61,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
61 select DVB_LGDT330X 61 select DVB_LGDT330X
62 select DVB_NXT200X 62 select DVB_NXT200X
63 select DVB_CX24123 63 select DVB_CX24123
64 select DVB_ISL6421
64 ---help--- 65 ---help---
65 This builds cx88-dvb with all currently supported frontend 66 This builds cx88-dvb with all currently supported frontend
66 demodulators. If you wish to tweak your configuration, and 67 demodulators. If you wish to tweak your configuration, and
@@ -139,6 +140,7 @@ config VIDEO_CX88_DVB_CX24123
139 default y 140 default y
140 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS 141 depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
141 select DVB_CX24123 142 select DVB_CX24123
143 select DVB_ISL6421
142 ---help--- 144 ---help---
143 This adds DVB-S support for cards based on the 145 This adds DVB-S support for cards based on the
144 Connexant 2388x chip and the CX24123 demodulator. 146 Connexant 2388x chip and the CX24123 demodulator.
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index ce225202f327..4d369f8393d9 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -59,6 +59,7 @@
59#ifdef HAVE_CX24123 59#ifdef HAVE_CX24123
60# include "cx24123.h" 60# include "cx24123.h"
61#endif 61#endif
62#include "isl6421.h"
62 63
63MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 64MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
64MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 65MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -479,28 +480,30 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe,
479 return 0; 480 return 0;
480} 481}
481 482
482static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) 483static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
483{ 484{
484 struct cx8802_dev *dev= fe->dvb->priv; 485 struct cx8802_dev *dev= fe->dvb->priv;
485 struct cx88_core *core = dev->core; 486 struct cx88_core *core = dev->core;
486 487
487 if (on) 488 if (voltage == SEC_VOLTAGE_OFF) {
488 cx_write(MO_GP0_IO, 0x000006f9);
489 else
490 cx_write(MO_GP0_IO, 0x000006fB); 489 cx_write(MO_GP0_IO, 0x000006fB);
490 } else {
491 cx_write(MO_GP0_IO, 0x000006f9);
492 }
493
494 if (core->prev_set_voltage)
495 return core->prev_set_voltage(fe, voltage);
496 return 0;
491} 497}
492 498
493static struct cx24123_config hauppauge_novas_config = { 499static struct cx24123_config hauppauge_novas_config = {
494 .demod_address = 0x55, 500 .demod_address = 0x55,
495 .use_isl6421 = 1,
496 .set_ts_params = cx24123_set_ts_param, 501 .set_ts_params = cx24123_set_ts_param,
497}; 502};
498 503
499static struct cx24123_config kworld_dvbs_100_config = { 504static struct cx24123_config kworld_dvbs_100_config = {
500 .demod_address = 0x15, 505 .demod_address = 0x15,
501 .use_isl6421 = 0,
502 .set_ts_params = cx24123_set_ts_param, 506 .set_ts_params = cx24123_set_ts_param,
503 .enable_lnb_voltage = cx24123_enable_lnb_voltage,
504}; 507};
505#endif 508#endif
506 509
@@ -710,10 +713,17 @@ static int dvb_register(struct cx8802_dev *dev)
710 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: 713 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
711 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, 714 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
712 &dev->core->i2c_adap); 715 &dev->core->i2c_adap);
716 if (dev->dvb.frontend) {
717 isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap, 0x08, 0x00, 0x00);
718 }
713 break; 719 break;
714 case CX88_BOARD_KWORLD_DVBS_100: 720 case CX88_BOARD_KWORLD_DVBS_100:
715 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, 721 dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
716 &dev->core->i2c_adap); 722 &dev->core->i2c_adap);
723 if (dev->dvb.frontend) {
724 dev->core->prev_set_voltage = dev->dvb.frontend->ops->set_voltage;
725 dev->dvb.frontend->ops->set_voltage = kworld_dvbs_100_set_voltage;
726 }
717 break; 727 break;
718#endif 728#endif
719 default: 729 default:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 8413e54ef4b8..411bb9f39c77 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -298,6 +298,7 @@ struct cx88_core {
298 /* config info -- dvb */ 298 /* config info -- dvb */
299 struct dvb_pll_desc *pll_desc; 299 struct dvb_pll_desc *pll_desc;
300 unsigned int pll_addr; 300 unsigned int pll_addr;
301 int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
301 302
302 /* state info */ 303 /* state info */
303 struct task_struct *kthread; 304 struct task_struct *kthread;