diff options
author | Andrew de Quincey <adq_dvb@lidskialf.net> | 2006-05-12 19:31:51 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2006-06-25 01:00:21 -0400 |
commit | cd20ca9f194323c74ecccf15a3f5ff6c44effe69 (patch) | |
tree | 36e8ad6eab353a34dec9713f9bfbfb7c5060a844 /drivers/media/dvb/frontends/cx24123.c | |
parent | 9a10655ffa20b596fd162b1c96301f3bed752918 (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>
Diffstat (limited to 'drivers/media/dvb/frontends/cx24123.c')
-rw-r--r-- | drivers/media/dvb/frontends/cx24123.c | 184 |
1 files changed, 48 insertions, 136 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 | ||
252 | static 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 | |||
275 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | 251 | static 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 | ||
298 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
299 | { | ||
300 | return state->lnbreg; | ||
301 | } | ||
302 | |||
303 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | 274 | static 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) | |||
763 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | 698 | static 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 | ||
800 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 733 | static 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; |